JAVA 非对称加密算法RSA

 

非对称加密算法 RSA过程 : 以甲乙双方为例
  1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中
    KeyPairGenerator ---> KeyPair --> RSAPublicKey、RSAPrivateKey
  2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方
    RSACoder.encryptByPrivateKey(data, privateKey);
    RSACoder.sign(encodedData, privateKey);
  3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密
    RSACoder.verify(encodedData, publicKey, sign);
    RSACoder.decryptByPublicKey(encodedData, publicKey);
   4、乙方在通过公钥加密发送给甲方
    RSACoder.encryptByPublicKey(decodedData, publicKey);
  5、甲方通过私钥解密该数据
    RSACoder.decryptPrivateKey(encodedData, privateKey);
流程图如下:

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

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

package com.bank.utils;

 

import java.security.MessageDigest;

 

import javax.crypto.KeyGenerator;

import javax.crypto.Mac;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;

 

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

public abstract class Coder {

    public static final String KEY_SHA = "SHA";

    public static final String KEY_MD5 = "MD5";

     

    /**

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

     

     * <pre>

     * HmacMD5 

     * HmacSHA1 

     * HmacSHA256 

     * HmacSHA384 

     * HmacSHA512

     * </pre>

     */ 

    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

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

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

package com.bank.utils;

 

import java.security.Key;

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;

import java.util.HashMap;

import java.util.Map;

 

import javax.crypto.Cipher;

 

 

public abstract class RSACoder extends Coder{

    public static final String KEY_ALGORITHM = "RSA";

    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

     

    private static final String PUBLIC_KEY = "RSAPublicKey";

    private static final String PRIVATE_KEY = "RSAPrivatekey";

     

    /**

     * 用私钥对信息生成数字签名

     * @param data 加密数据

     * @param privateKey 私钥

     * @return

     * @throws Exception

     */

    public static String sign(byte[] data, String privateKey) throws Exception {

        //解密由base64编码的私钥

        byte[] keyBytes = decryptBASE64(privateKey);

         

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);

         

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

         

        //取私钥对象

        PrivateKey pKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

         

        //用私钥生成数字签名

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

        signature.initSign(pKey);

        signature.update(data);

         

        return encryptBASE64(signature.sign());

    }

     

    /**

     * 校验数字签名

     * @param data 加密数据

     * @param publicKey 公钥

     * @param sign 数字签名

     * @return

     * @throws Exception

     */

    public static boolean verify(byte[] data, String publicKey, String sign) throws Exception{

         

        //解密有base64编码的公钥

        byte[] keyBytes = decryptBASE64(publicKey);

         

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

         

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

         

        //取公钥对象

        PublicKey pKey = keyFactory.generatePublic(keySpec);

         

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

        signature.initVerify(pKey);

        signature.update(data);

        //验证签名是否正常

        return signature.verify(decryptBASE64(sign));

    }

     

    /**

     * 解密

     *  用私钥解密

     * @param data 加密数据

     * @param key

     * @return

     * @throws Exception

     */

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

        byte[] keyBytes = decryptBASE64(key);

         

        //取得私钥

        PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);

        KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);

        Key pKey = factory.generatePrivate(encodedKeySpec);

         

        //对数据解密

        Cipher cipher = Cipher.getInstance(factory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE, pKey);

         

        return cipher.doFinal(data);

    }

     

    /**

     * 用公钥解密

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

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

         

        //解密

        byte[] keyBytes = decryptBASE64(key);

         

        //取得公钥

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        Key pKey = keyFactory.generatePublic(keySpec);

         

        //对数据解密

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.DECRYPT_MODE, pKey);

         

        return cipher.doFinal(data);

    }

     

    /**

     * 用公钥加密

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

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

         

        byte[] keyBytes = decryptBASE64(key);

         

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        Key pKey = keyFactory.generatePublic(keySpec);

         

         

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE, pKey);

         

        return cipher.doFinal(data);

    }

     

    /**

     * 用私钥加密

     * @param data

     * @param key

     * @return

     * @throws Exception

     */

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

         

        byte[] keyBytes = decryptBASE64(key);

         

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        Key privateKey = keyFactory.generatePrivate(keySpec);

         

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

        cipher.init(Cipher.ENCRYPT_MODE, privateKey);

         

        return cipher.doFinal(data);

    }

     

    /**

     * 取得私钥

     * @param keyMap

     * @return

     * @throws Exception

     */

    public static String getPrivateKey( Map<String, Object> keyMap) throws Exception{

 

        Key key = (Key) keyMap.get(PRIVATE_KEY);

         

        return encryptBASE64(key.getEncoded());

    }

     

    /**

     * 取得公钥

     * @param keyMap

     * @return

     * @throws Exception

     */

    public static String getPublicKey( Map<String, Object> keyMap) throws Exception{

 

        Key key = (Key) keyMap.get(PUBLIC_KEY);

         

        return encryptBASE64(key.getEncoded());

    }

    /**

     * 初始化密钥

     * @return

     * @throws Exception

     */

    public static Map<String, Object> initKey() throws Exception{

         

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);

        keyPairGenerator.initialize(1024);

         

        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        //公钥

        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

         

        //私钥

        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

         

        Map<String, Object> keyMap = new HashMap<String, Object>(2);

        keyMap.put(PRIVATE_KEY, privateKey);

        keyMap.put(PUBLIC_KEY, publicKey);

        return keyMap;

    }

}

  

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

package com.bank.test;

 

import java.util.Map;

 

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

 

import com.bank.utils.RSACoder;

 

public class RSACoderTest {

    private String publicKey;

    private String privateKey;

    /*

     * 非对称加密算法   RSA过程 : 以甲乙双方为例

     *      1、初始化密钥 构建密钥对,生成公钥、私钥保存到keymap中

     *              KeyPairGenerator --->    KeyPair     -->      RSAPublicKey、RSAPrivateKey

     *      2、甲方使用私钥加密, 加密后在用私钥对加密数据进行数据签名,然后发送给乙方

     *              RSACoder.encryptByPrivateKey(data, privateKey);

     *              RSACoder.sign(encodedData, privateKey);

     *      3、乙方则通过公钥验证签名的加密数据,如果验证正确则在通过公钥对加密数据进行解密

     *              RSACoder.verify(encodedData, publicKey, sign);

     *              RSACoder.decryptByPublicKey(encodedData, publicKey);               

     *

     *      4、乙方在通过公钥加密发送给甲方

     *              RSACoder.encryptByPublicKey(decodedData, publicKey);

     *      5、甲方通过私钥解密该数据      

     *              RSACoder.decryptPrivateKey(encodedData, privateKey);               

     */

    @Before

    public void setUp() throws Exception {

         

        Map<String , Object> keyMap = RSACoder.initKey();

         

        publicKey = RSACoder.getPublicKey(keyMap);

        privateKey = RSACoder.getPrivateKey(keyMap);

         

        System.out.println("公钥:\n" + publicKey);

        System.out.println("私钥:\n" + privateKey);

    }

    @Test

    public void test() throws Exception{

        String inputStr = "abc";

        byte[] data = inputStr.getBytes();//每次的得到的字节数组是不一样的。

        //第二步 私钥加密

        byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

        //私钥进行数据签名

        String sign = RSACoder.sign(encodedData, privateKey);

         

        //第三步 公钥验证数字签名

        boolean flag = RSACoder.verify(encodedData, publicKey, sign);

        System.out.println("flag:" + flag);

        //用公钥对数据解密

        byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);

         

        System.out.println("data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);

        System.out.println("加密前数据-:" new String(data) + "     解密后数据: " new String(decodedData));

         

        //第四步使用公钥加密数据

        encodedData = RSACoder.encryptByPublicKey(decodedData, publicKey);

         

        //第五步 使用私钥解密数据

        decodedData = RSACoder.decryptPrivateKey(encodedData, privateKey);

         

         

        System.out.println("data:" + data + "加密数据:" + encodedData + "    解密数据:" + decodedData);

        System.out.println("加密前数据:" + inputStr + "     解密后数据: " new String(decodedData));

    }

     

     

    @Test

    public void test1() throws Exception{

        System.out.println("私钥加密-----公钥解密");

        String inputStr = "abc";

        byte[] data = inputStr.getBytes();

        System.out.println("data:" + data);

         

        byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);

        byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);

     

        String outputStr = new String( decodedData );

         

        System.out.println("加密前:" + inputStr +"\n 解密后:" + outputStr);

         

        Assert.assertEquals(inputStr, outputStr);

         

         

        System.out.println("私钥签名---公钥验证签名");

        //产生签名

        String sign = RSACoder.sign(encodedData, privateKey);

        System.out.println("签名:\r" + sign);

         

        //验证签名

        boolean flag = RSACoder.verify(encodedData, publicKey, sign);

         

        System.out.println("状态:\r" + flag);

         

        Assert.assertTrue(flag);

    }

}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值