java中常用的加密方法

加密介绍

在对用户的一些重要信息和隐私信息,或者是公司的信息进行保存的时候,又或者是在发送信息的时候,我们不希望别人能看见这些信息
是什么东西,或者是被别人抓包获取或者是截取到信息时,是一些意义不明的字符,所以也就需要加密方法。

加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息
的内容。

越重要的信息,所需要的加密算法就越是复杂,计算量就越大,时间就越长,破解也就越麻烦。

加密的分类

加密分为单向加密以及双向加密,而双向加密又分为对称加密和非对称加密。

单向加密:是对信息进行了摘要计算,不能通过算法生成明文,单向加密从严格意思上说不能算是加密的一种,应该算是摘要算法。
双向加密:明文加密后形成密文,可以通过算法还原成明文。
对称加密:双方使用的秘钥是同一把秘钥。
非对称加密:双方使用的是不同的秘钥,或者是都有各自的一把钥匙。

单向加密

java的jdk中有提供基础的加密算法,在Apache公司提供的org.apache.commons.codec里,基本使用jdk的加密方法就够了。

Base64加密

采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。就是将信息每个字符都转变成定义的64个字符,这样就隐藏了信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.amuro.strategy.base64;

import java.util.Base64;

import com.amuro.strategy.IStrategy;

/**
* Base64算法基于64个基本字符,加密后的string中只包含这64个字符
*
*/
public class Base64Strategy implements IStrategy
{
public String encode(String src)
{
byte[] encodeBytes = Base64.getEncoder().encode(src.getBytes());
return new String(encodeBytes);
}

public String decode(String src)
{
byte[] decodeBytes = Base64.getDecoder().decode(src.getBytes());
return new String(decodeBytes);
}
}

md5消息摘要

消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数
对消息进行作用而产生。HASH函数的抗冲突性使得如果一段明文稍有变化,哪怕只更改该段落的一个字母,通过哈希算法作用后都将产生不同的值。而
HASH算法的单向性使得要找到哈希值相同的两个不同的输入消息,在计算上是不可能的。所以数据的哈希值,即消息摘要,可以检验数据的完整性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.amuro.strategy.message_digest;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
* 消息摘要算法
*
*/
public class MD5Strategy implements IStrategy
{

public String encode(String src)
{
try
{
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] encodeBytes = md.digest(src.getBytes());

return Hex.encodeHexString(encodeBytes);
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return null;
}

public String decode(String src)
{
throw new RuntimeException("MD5 no decode");
}

}

sha-1消息摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.amuro.strategy.message_digest;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
* 安全散列算法
*
*/
public class SHAStrategy implements IStrategy
{

public String encode(String src)
{
try
{
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(src.getBytes());
return Hex.encodeHexString(md.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return null;
}

public String decode(String src)
{
throw new RuntimeException("SHA no decode");
}

}

对称加密

DES

DES,全称为“Data Encryption Standard”,中文名为“数据加密标准”,是一种使用密钥加密的块算法。DES 算法为密码体制中的对称密码体制,又被
称为美国数据加密标准,是 1972 年美国 IBM 公司研制的对称密码体制加密算法。 明文按 64 位进行分组,密钥长 64 位,密钥事实上是 56 位参与
DES 运算(第8、16、24、32、40、48、56、64 位是校验位, 使得每个密钥都有奇数个 1)分组后的明文组和 56 位的密钥按位替代或交换的方法形成
密文组的加密方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.amuro.strategy.des;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class DESStrategy implements IStrategy
{
private Cipher cipher;
private SecretKey generateKey;

public String encode(String src)
{
try
{
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
keyGenerator.init(56);//size
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();

DESKeySpec desKeySpec = new DESKeySpec(keyBytes);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
generateKey = secretKeyFactory.generateSecret(desKeySpec);

cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, generateKey);
byte[] resultBytes = cipher.doFinal(src.getBytes());

return Hex.encodeHexString(resultBytes);
}
catch (Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
cipher.init(Cipher.DECRYPT_MODE, generateKey);
byte[] result = Hex.decodeHex(src.toCharArray());
return new String(cipher.doFinal(result));
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

}

3DES3DES

Triple DES,中文名“三重数据加密算法”,它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密
钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新
的块密码算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.amuro.strategy.des;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class _3DESStrategy implements IStrategy
{
private Cipher cipher;
private SecretKey generateKey;

public String encode(String src)
{
try
{
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
keyGenerator.init(168);//size
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();

DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
generateKey = secretKeyFactory.generateSecret(desKeySpec);

cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, generateKey);
byte[] resultBytes = cipher.doFinal(src.getBytes());

return Hex.encodeHexString(resultBytes);
}
catch (Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
cipher.init(Cipher.DECRYPT_MODE, generateKey);
byte[] result = Hex.decodeHex(src.toCharArray());
return new String(cipher.doFinal(result));
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}
}

AESAES

全称为“Advanced Encryption Standard”,中文名“高级加密标准”,在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标
准。AES 加密算法作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES 设计有三个密钥长度:128,192,256 位。
相对而言,AES 的 128 密钥比 DES 的 56 密钥强了 1021 倍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.amuro.strategy.des;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class AESStrategy implements IStrategy
{
private Cipher cipher;
private SecretKey generateKey;

public String encode(String src)
{
try
{
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);//size
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();

generateKey = new SecretKeySpec(keyBytes, "AES");

cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, generateKey);
byte[] resultBytes = cipher.doFinal(src.getBytes());

return Hex.encodeHexString(resultBytes);
}
catch (Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
cipher.init(Cipher.DECRYPT_MODE, generateKey);
byte[] result = Hex.decodeHex(src.toCharArray());
return new String(cipher.doFinal(result));
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}
}

PBE

PBE,全称为“Password Base Encryption”,中文名“基于口令加密”,是一种基于密码的加密算法,其特点是使用口令代替了密钥,
而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。PBE算法没有密钥的概念,把口令当做密钥了。因为密钥
长短影响算法安全性,还不方便记忆,这里我们直接换成我们自己常用的口令就大大不同了,便于我们的记忆。但是单纯的口令很容易
被字典法给穷举出来,所以我们这里给口令加了点“盐”,这个盐和口令组合,想破解就难了。同时我们将盐和口令合并后用消息摘要算
法进行迭代很多次来构建密钥初始化向量的基本材料,使破译更加难了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.amuro.strategy.pbe;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

/**
* 基于口令的加密(password),对称 + 消息摘要
*
*/
public class PBEStrategy implements IStrategy
{
private Cipher cipher;
private SecretKey generateKey;
private PBEParameterSpec pbeParameterSpec;

public String encode(String src)
{
try
{
SecureRandom secureRandom = new SecureRandom();
byte[] salt = secureRandom.generateSeed(8);

String password = "amuro";
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
generateKey = secretKeyFactory.generateSecret(pbeKeySpec);

pbeParameterSpec = new PBEParameterSpec(salt, 100);
cipher = Cipher.getInstance("PBEWITHMD5andDES");
cipher.init(Cipher.ENCRYPT_MODE, generateKey, pbeParameterSpec);
byte[] resultBytes = cipher.doFinal(src.getBytes());
return Hex.encodeHexString(resultBytes);
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
cipher.init(Cipher.DECRYPT_MODE, generateKey, pbeParameterSpec);
byte[] result = Hex.decodeHex(src.toCharArray());
return new String(cipher.doFinal(result));
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

}

非对称加密

非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥。需要注意的一点,这个公钥和私钥必须是一对的,如果用公钥对数据进行加
密,那么只有使用对应的私钥才能解密,反之亦然。由于加密和解密使用的是两个不同的密钥,因此,这种算法叫做非对称加密算法。

RSA

在 1978 年的时候,RSA就已经出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。其原理就如上面
的工作过程所述。RSA 算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将
乘积公开作为加密密钥。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.amuro.strategy.asymmetric;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class RSAStrategy implements IStrategy
{
private RSAPublicKey rsaPublicKey;
private RSAPrivateKey rsaPrivateKey;

public String encode(String src)
{
try
{
//初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();

//私钥加密 公钥解密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec
= new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] resultBytes = cipher.doFinal(src.getBytes());

//私钥解密 公钥加密
// X509EncodedKeySpec x509EncodedKeySpec =
// new X509EncodedKeySpec(rsaPublicKey.getEncoded());
// KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// Cipher cipher = Cipher.getInstance("RSA");
// cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// byte[] resultBytes = cipher.doFinal(src.getBytes());

return Hex.encodeHexString(resultBytes);
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
//私钥加密 公钥解密
X509EncodedKeySpec x509EncodedKeySpec =
new X509EncodedKeySpec(rsaPublicKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));

//私钥解密 公钥加密
// PKCS8EncodedKeySpec pkcs8EncodedKeySpec
// = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
// KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// Cipher cipher = Cipher.getInstance("RSA");
// cipher.init(Cipher.DECRYPT_MODE, privateKey);
// byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));

return new String(resultBytes);
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}

}

DH算法

DH,全称为“Diffie-Hellman”,他是一种确保共享KEY安全穿越不安全网络的方法,也就是常说的密钥一致协议。由公开密钥密码体制的奠基人Diffie和
Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成“一致”的、可以共享的密钥。也就是由甲方产出一对密钥(公钥、私钥),
乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对
数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公
钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.amuro.strategy.asymmetric;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

import org.apache.commons.codec.binary.Hex;

import com.amuro.strategy.IStrategy;

public class DHStrategy implements IStrategy
{
private Cipher cipher;
private SecretKey receiverSecretKey;

public String encode(String src)
{
try
{
//初始化发送方密钥
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
senderKeyPairGenerator.initialize(512);
KeyPair senderkeyPair = senderKeyPairGenerator.generateKeyPair();
PrivateKey senderPrivateKey = senderkeyPair.getPrivate();
byte[] senderPublicKeyBytes = senderkeyPair.getPublic().getEncoded();//发送方的公钥

//初始化接收方密钥,用发送方的公钥
KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyBytes);
PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
DHParameterSpec dhParameterSpec =
((DHPublicKey)receiverPublicKey).getParams();
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
receiverKeyPairGenerator.initialize(dhParameterSpec);
KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic().getEncoded();

KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
receiverKeyAgreement.init(receiverPrivateKey);
receiverKeyAgreement.doPhase(receiverPublicKey, true);
receiverSecretKey = receiverKeyAgreement.generateSecret("DES");

//发送方拿到接收方的public key就可以做加密了
KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyBytes);
PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);
KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
senderKeyAgreement.init(senderPrivateKey);
senderKeyAgreement.doPhase(senderPublicKey, true);
SecretKey senderSecretKey = senderKeyAgreement.generateSecret("DES");

if(Objects.equals(receiverSecretKey, senderSecretKey))
{
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
byte[] result = cipher.doFinal(src.getBytes());
return Hex.encodeHexString(result);
}

}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

public String decode(String src)
{
try
{
cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
byte[] result = Hex.decodeHex(src.toCharArray());
return new String(cipher.doFinal(result));
}
catch(Exception e)
{
e.printStackTrace();
}

return null;
}

}

数字签名证书

非对称加密已经灰常安全了,但是还有一个破绽:
服务器A公布了自己的公钥,我的电脑是用服务器A的公钥加密数据后再发给服务器A的;这时候服务器B侵入了我的电脑,把我用来加密的公钥换成了它的公钥,于是我发出去的数据就会被服务器B的私钥破解了。肿么防止公钥被篡改呢?
对,我们想到了前面的消息摘要,服务器A把公钥丢给我的时候,同时去CA申请一份数字证书,其实主要就是公钥的消息摘要,有了这份证书,当我再用公钥加密的时候,我就可以先验证一下当前的公钥是否确定是服务器A发送给我的。
这里就贴一种RSA的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.amuro.strategy.signature;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSASign
{
public static boolean verifySign(String src)
{
try
{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
PrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();

PKCS8EncodedKeySpec pkcs8EncodedKeySpec
= new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(src.getBytes());
//生成签名bytes
byte[] signBytes = signature.sign();

X509EncodedKeySpec x509EncodedKeySpec =
new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean isVerified = signature.verify(signBytes);

return isVerified;
}
catch(Exception e)
{
e.printStackTrace();
}

return false;
}

}