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);
     }
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值