各种Java加密算法-对称加密

如基本的单向加密算法:  

  • BASE64 严格地说,属于编码格式,而非加密算法

  • MD5(Message Digest algorithm 5,信息摘要算法)

  • SHA(Secure Hash Algorithm,安全散列算法)

  • HMAC(Hash Message Authentication Code,散列消息鉴别码)


    复杂的对称加密(DES、PBE)、非对称加密算法: 

  • DES(Data Encryption Standard,数据加密算法)

  • PBE(Password-based encryption,基于密码验证)

  • RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)

  • DH(Diffie-Hellman算法,密钥一致协议)

  • DSA(Digital Signature Algorithm,数字签名)

  • ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)



    本篇内容简要介绍BASE64MD5SHAHMAC几种方法。 
    MD5SHAHMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。 

BASE64 
按 照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 
常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。 

各种Java加密算法-对称加密_第1张图片 

通过java代码实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/**

     * BASE64解密

     

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] decryptBASE64(String key) throws Exception {

        return (new BASE64Decoder()).decodeBuffer(key);

    }

 

    /**

     * BASE64加密

     

     * @param key

     * @return

     * @throws Exception

     */

    public static String encryptBASE64(byte[] key) throws Exception {

        return (new BASE64Encoder()).encodeBuffer(key);

    }


主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。 

MD5 
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都 是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文 件是否一致的。 

各种Java加密算法-对称加密_第2张图片 

通过java代码实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

/**

     * MD5加密

     

     * @param data

     * @return

     * @throws Exception

     */

    public static byte[] encryptMD5(byte[] data) throws Exception {

 

        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);

        md5.update(data);

 

        return md5.digest();

 

    }



通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。 

SHA 
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全。 

各种Java加密算法-对称加密_第3张图片 

通过java代码实现如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

     * SHA加密

     

     * @param data

     * @return

     * @throws Exception

     */

    public static byte[] encryptSHA(byte[] data) throws Exception {

 

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);

        sha.update(data);

 

        return sha.digest();

 

    }

}



HMAC 
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个 标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证 等。 

各种Java加密算法-对称加密_第4张图片 

通过java代码实现如下:

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

/**

     * 初始化HMAC密钥

     

     * @return

     * @throws Exception

     */

    public static String initMacKey() throws Exception {

        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

 

        SecretKey secretKey = keyGenerator.generateKey();

        return encryptBASE64(secretKey.getEncoded());

    }

 

    /**

     * HMAC加密

     

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

 

        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);

        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        mac.init(secretKey);

 

        return mac.doFinal(data);

 

    }



给出一个完整类,如下:

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

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

import java.security.MessageDigest;

 

import javax.crypto.KeyGenerator;

import javax.crypto.Mac;

import javax.crypto.SecretKey;

 

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

/**

 * 基础加密组件

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public abstract class Coder {

    public static final String KEY_SHA = "SHA";

    public static final String KEY_MD5 = "MD5";

 

    /**

     * MAC算法可选以下多种算法

     

     

     * HmacMD5 

     * HmacSHA1 

     * HmacSHA256 

     * HmacSHA384 

     * HmacSHA512

     

     */

    public static final String KEY_MAC = "HmacMD5";

 

    /**

     * BASE64解密

     

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] decryptBASE64(String key) throws Exception {

        return (new BASE64Decoder()).decodeBuffer(key);

    }

 

    /**

     * BASE64加密

     

     * @param key

     * @return

     * @throws Exception

     */

    public static String encryptBASE64(byte[] key) throws Exception {

        return (new BASE64Encoder()).encodeBuffer(key);

    }

 

    /**

     * MD5加密

     

     * @param data

     * @return

     * @throws Exception

     */

    public static byte[] encryptMD5(byte[] data) throws Exception {

 

        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);

        md5.update(data);

 

        return md5.digest();

 

    }

 

    /**

     * SHA加密

     

     * @param data

     * @return

     * @throws Exception

     */

    public static byte[] encryptSHA(byte[] data) throws Exception {

 

        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);

        sha.update(data);

 

        return sha.digest();

 

    }

 

    /**

     * 初始化HMAC密钥

     

     * @return

     * @throws Exception

     */

    public static String initMacKey() throws Exception {

        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

 

        SecretKey secretKey = keyGenerator.generateKey();

        return encryptBASE64(secretKey.getEncoded());

    }

 

    /**

     * HMAC加密

     

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

 

        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);

        Mac mac = Mac.getInstance(secretKey.getAlgorithm());

        mac.init(secretKey);

 

        return mac.doFinal(data);

 

    }

}



再给出一个测试类:

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

import static org.junit.Assert.*;

 

import org.junit.Test;

 

/**

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public class CoderTest {

 

    @Test

    public void test() throws Exception {

        String inputStr = "简单加密";

        System.err.println("原文:\n" + inputStr);

 

        byte[] inputData = inputStr.getBytes();

        String code = Coder.encryptBASE64(inputData);

 

        System.err.println("BASE64加密后:\n" + code);

 

        byte[] output = Coder.decryptBASE64(code);

 

        String outputStr = new String(output);

 

        System.err.println("BASE64解密后:\n" + outputStr);

 

        // 验证BASE64加密解密一致性

        assertEquals(inputStr, outputStr);

 

        // 验证MD5对于同一内容加密是否一致

        assertArrayEquals(Coder.encryptMD5(inputData), Coder

                .encryptMD5(inputData));

 

        // 验证SHA对于同一内容加密是否一致

        assertArrayEquals(Coder.encryptSHA(inputData), Coder

                .encryptSHA(inputData));

 

        String key = Coder.initMacKey();

        System.err.println("Mac密钥:\n" + key);

 

        // 验证HMAC对于同一内容,同一密钥加密是否一致

        assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(

                inputData, key));

 

        BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));

        System.err.println("MD5:\n" + md5.toString(16));

 

        BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));

        System.err.println("SHA:\n" + sha.toString(32));

 

        BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));

        System.err.println("HMAC:\n" + mac.toString(16));

    }

}



控制台输出:

原文:
简单加密
BASE64加密后:
566A5Y2V5Yqg5a+G

BASE64解密后:
简单加密
Mac密钥:
uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke
pBIpkd7QHg==

MD5:
-550b4d90349ad4629462113e7934de56
SHA:
91k9vo7p400cjkgfhjh0ia9qthsjagfn
HMAC:
2287d192387e95694bdbba2fa941009a



注意 
编译时,可能会看到如下提示: 

引用


警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在未来版本中删除 

import sun.misc.BASE64Decoder; 
               ^ 
警告:sun.misc.BASE64Encoder 是 Sun 的专用 API,可能会在未来版本中删除 

import sun.misc.BASE64Encoder; 
               ^ 



BASE64Encoder 和BASE64Decoder是非官方JDK实现类。虽然可以在JDK里能找到并使用,但是在API里查不到。JRE 中 sun 和 com.sun 开头包的类都是未被文档化的,他们属于 java, javax 类库的基础,其中的实现大多数与底层平台有关,一般来说是不推荐使用的。 


    BASE64的加密解密是双向的,可以求反解。 
    MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。 
    单向加密的用途主要是为了校验数据在传输过程中是否被修改。

    接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法。 
DES 
DES-Data Encryption Standard,即数据加密算法。是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中 Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密 或解密。 
        DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。 


通过java代码实现如下:Coder类见

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

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

import java.security.Key;

import java.security.SecureRandom;

 

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.DESKeySpec;

 

 

/**

 * DES安全编码组件

 

 

 * 支持 DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)

 * DES                  key size must be equal to 56

 * DESede(TripleDES)     key size must be equal to 112 or 168

 * AES                  key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available

 * Blowfish          key size must be multiple of 8, and can only range from 32 to 448 (inclusive)

 * RC2                  key size must be between 40 and 1024 bits

 * RC4(ARCFOUR)      key size must be between 40 and 1024 bits

 * 具体内容 需要关注 JDK Document http://.../docs/technotes/guides/security/SunProviders.html

 

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public abstract class DESCoder extends Coder {

    /**

     * ALGORITHM 算法 

     * 可替换为以下任意一种算法,同时key值的size相应改变。

     

     

     * DES                  key size must be equal to 56

     * DESede(TripleDES)     key size must be equal to 112 or 168

     * AES                  key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available

     * Blowfish          key size must be multiple of 8, and can only range from 32 to 448 (inclusive)

     * RC2                  key size must be between 40 and 1024 bits

     * RC4(ARCFOUR)      key size must be between 40 and 1024 bits

     

     

     * 在Key toKey(byte[] key)方法中使用下述代码

     SecretKey secretKey = new SecretKeySpec(key, ALGORITHM); 替换

     

     * DESKeySpec dks = new DESKeySpec(key);

     * SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);

     * SecretKey secretKey = keyFactory.generateSecret(dks);

     

     */

    public static final String ALGORITHM = "DES";

 

    /**

     * 转换密钥

     

     * @param key

     * @return

     * @throws Exception

     */

    private static Key toKey(byte[] key) throws Exception {

        DESKeySpec dks = new DESKeySpec(key);

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);

        SecretKey secretKey = keyFactory.generateSecret(dks);

 

        // 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码

        // SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);

 

        return secretKey;

    }

 

    /**

     * 解密

     

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] decrypt(byte[] data, String key) throws Exception {

        Key k = toKey(decryptBASE64(key));

 

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE, k);

 

        return cipher.doFinal(data);

    }

 

    /**

     * 加密

     

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

    public static byte[] encrypt(byte[] data, String key) throws Exception {

        Key k = toKey(decryptBASE64(key));

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE, k);

 

        return cipher.doFinal(data);

    }

 

    /**

     * 生成密钥

     

     * @return

     * @throws Exception

     */

    public static String initKey() throws Exception {

        return initKey(null);

    }

 

    /**

     * 生成密钥

     

     * @param seed

     * @return

     * @throws Exception

     */

    public static String initKey(String seed) throws Exception {

        SecureRandom secureRandom = null;

 

        if (seed != null) {

            secureRandom = new SecureRandom(decryptBASE64(seed));

        else {

            secureRandom = new SecureRandom();

        }

 

        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);

        kg.init(secureRandom);

 

        SecretKey secretKey = kg.generateKey();

 

        return encryptBASE64(secretKey.getEncoded());

    }

}


延续上一个类的实现,我们通过MD5以及SHA对字符串加密生成密钥,这是比较常见的密钥生成方式。 
再给出一个测试类:

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

import static org.junit.Assert.*;

 

 

import org.junit.Test;

 

/**

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public class DESCoderTest {

 

    @Test

    public void test() throws Exception {

        String inputStr = "DES";

        String key = DESCoder.initKey();

        System.err.println("原文:\t" + inputStr);

 

        System.err.println("密钥:\t" + key);

 

        byte[] inputData = inputStr.getBytes();

        inputData = DESCoder.encrypt(inputData, key);

 

        System.err.println("加密后:\t" + DESCoder.encryptBASE64(inputData));

 

        byte[] outputData = DESCoder.decrypt(inputData, key);

        String outputStr = new String(outputData);

 

        System.err.println("解密后:\t" + outputStr);

 

        assertEquals(inputStr, outputStr);

    }

}


得到的输出内容如下:

原文:	DES
密钥:	f3wEtRrV6q0=

加密后:	C6qe9oNIzRY=

解密后:	DES


    由控制台得到的输出,我们能够比对加密、解密后结果一致。这是一种简单的加密解密方式,只有一个密钥。 
    其实DES有很多同胞兄弟,如DESede(TripleDES)、AES、Blowfish、RC2、RC4(ARCFOUR)。这里就不过多阐述了,大同小异,只要换掉ALGORITHM换成对应的值,同时做一个代码替换SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);就可以了,此外就是密钥长度不同了。 

1

2

3

4

5

6

7

8

/**

 * DES          key size must be equal to 56

 * DESede(TripleDES) key size must be equal to 112 or 168

 * AES          key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available

 * Blowfish     key size must be multiple of 8, and can only range from 32 to 448 (inclusive)

 * RC2          key size must be between 40 and 1024 bits

 * RC4(ARCFOUR) key size must be between 40 and 1024 bits

 **/

    除了DES,我们还知道有DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)等多种对称加密方式,其实现方式大同小异,这里介绍对称加密的另一个算法——PBE 
PBE 
    PBE——Password-based encryption(基于密码加密)。其特点在于口令由用户自己掌管,不借助任何物理媒体;采用随机数(这里我们叫做盐)杂凑多重加密等方法保证数据的安全性。是一种简便的加密方式。 
通过java代码实现如下:Coder类见 

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

97

98

99

100

101

import java.security.Key;

import java.util.Random;

  

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.spec.PBEParameterSpec;

  

/**

 * PBE安全编码组件

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public abstract class PBECoder extends Coder {

    /**

     * 支持以下任意一种算法

     

     

     * PBEWithMD5AndDES 

     * PBEWithMD5AndTripleDES 

     * PBEWithSHA1AndDESede

     * PBEWithSHA1AndRC2_40

     

     */

    public static final String ALGORITHM = "PBEWITHMD5andDES";

  

    /**

     * 盐初始化

     

     * @return

     * @throws Exception

     */

    public static byte[] initSalt() throws Exception {

        byte[] salt = new byte[8];

        Random random = new Random();

        random.nextBytes(salt);

        return salt;

    }

  

    /**

     * 转换密钥

     

     * @param password

     * @return

     * @throws Exception

     */

    private static Key toKey(String password) throws Exception {

        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);

        SecretKey secretKey = keyFactory.generateSecret(keySpec);

  

        return secretKey;

    }

  

    /**

     * 加密

     

     * @param data 数据

     * @param password 密码

     * @param salt  盐

     * @return

     * @throws Exception

     */

    public static byte[] encrypt(byte[] data, String password, byte[] salt)

            throws Exception {

  

        Key key = toKey(password);

  

        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

  

        return cipher.doFinal(data);

  

    }

  

    /**

     * 解密

     

     * @param data  数据

     * @param password 密码

     * @param salt  盐

     * @return

     * @throws Exception

     */

    public static byte[] decrypt(byte[] data, String password, byte[] salt)

            throws Exception {

  

        Key key = toKey(password);

  

        PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);

        Cipher cipher = Cipher.getInstance(ALGORITHM);

        cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

  

        return cipher.doFinal(data);

  

    }

}



再给出一个测试类: 

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

import static org.junit.Assert.*;

  

import org.junit.Test;

  

/**

 

 * @author 梁栋

 * @version 1.0

 * @since 1.0

 */

public class PBECoderTest {

  

    @Test

    public void test() throws Exception {

        String inputStr = "abc";

        System.err.println("原文: " + inputStr);

        byte[] input = inputStr.getBytes();

  

        String pwd = "efg";

        System.err.println("密码: " + pwd);

  

        byte[] salt = PBECoder.initSalt();

  

        byte[] data = PBECoder.encrypt(input, pwd, salt);

  

        System.err.println("加密后: " + PBECoder.encryptBASE64(data));

  

        byte[] output = PBECoder.decrypt(data, pwd, salt);

        String outputStr = new String(output);

  

        System.err.println("解密后: " + outputStr);

        assertEquals(inputStr, outputStr);

    }

  

}



控制台输出: 

原文: abc
密码: efg
加密后: iCZ0uRtaAhE=
 
解密后: abc


    后续我们会介绍非对称加密算法,如RSA、DSA、DH、ECC等。 

    接下来我们介绍典型的非对称加密算法——RSA 

你可能感兴趣的:(java基础)