java加密算法非对称加密算法——RSA

RSA 
    这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。 
    这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥 匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。 

流程分析: 

  1. 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。

  2. 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。

  3. 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。



按如上步骤给出序列图,如下: 

  1. 各种Java加密算法

  2. 各种Java加密算法

  3. 各种Java加密算法



通过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
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
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;
 
/**
  * RSA安全编码组件
 
  * @author 梁栋
  * @version 1.0
  * @since 1.0
  */
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 pkcs8KeySpec =  new  PKCS8EncodedKeySpec(keyBytes);
 
         // KEY_ALGORITHM 指定的加密算法
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 
         // 取私钥匙对象
         PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
         // 用私钥对信息生成数字签名
         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
         signature.initSign(priKey);
         signature.update(data);
 
         return  encryptBASE64(signature.sign());
     }
 
     /**
      * 校验数字签名
     
      * @param data
      *            加密数据
      * @param publicKey
      *            公钥
      * @param sign
      *            数字签名
     
      * @return 校验成功返回true 失败返回false
      * @throws Exception
     
      */
     public  static  boolean  verify( byte [] data, String publicKey, String sign)
             throws  Exception {
 
         // 解密由base64编码的公钥
         byte [] keyBytes = decryptBASE64(publicKey);
 
         // 构造X509EncodedKeySpec对象
         X509EncodedKeySpec keySpec =  new  X509EncodedKeySpec(keyBytes);
 
         // KEY_ALGORITHM 指定的加密算法
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
 
         // 取公钥匙对象
         PublicKey pubKey = keyFactory.generatePublic(keySpec);
 
         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
         signature.initVerify(pubKey);
         signature.update(data);
 
         // 验证签名是否正常
         return  signature.verify(decryptBASE64(sign));
     }
 
     /**
      * 解密<br>
      * 用私钥解密
     
      * @param data
      * @param key
      * @return
      * @throws Exception
      */
     public  static  byte [] decryptByPrivateKey( byte [] data, String key)
             throws  Exception {
         // 对密钥解密
         byte [] keyBytes = decryptBASE64(key);
 
         // 取得私钥
         PKCS8EncodedKeySpec pkcs8KeySpec =  new  PKCS8EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
         // 对数据解密
         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
         cipher.init(Cipher.DECRYPT_MODE, privateKey);
 
         return  cipher.doFinal(data);
     }
 
     /**
      * 解密<br>
      * 用私钥解密
     
      * @param data
      * @param key
      * @return
      * @throws Exception
      */
     public  static  byte [] decryptByPublicKey( byte [] data, String key)
             throws  Exception {
         // 对密钥解密
         byte [] keyBytes = decryptBASE64(key);
 
         // 取得公钥
         X509EncodedKeySpec x509KeySpec =  new  X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
         Key publicKey = keyFactory.generatePublic(x509KeySpec);
 
         // 对数据解密
         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
         cipher.init(Cipher.DECRYPT_MODE, publicKey);
 
         return  cipher.doFinal(data);
     }
 
     /**
      * 加密<br>
      * 用公钥加密
     
      * @param data
      * @param key
      * @return
      * @throws Exception
      */
     public  static  byte [] encryptByPublicKey( byte [] data, String key)
             throws  Exception {
         // 对公钥解密
         byte [] keyBytes = decryptBASE64(key);
 
         // 取得公钥
         X509EncodedKeySpec x509KeySpec =  new  X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
         Key publicKey = keyFactory.generatePublic(x509KeySpec);
 
         // 对数据加密
         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
 
         return  cipher.doFinal(data);
     }
 
     /**
      * 加密<br>
      * 用私钥加密
     
      * @param data
      * @param key
      * @return
      * @throws Exception
      */
     public  static  byte [] encryptByPrivateKey( byte [] data, String key)
             throws  Exception {
         // 对密钥解密
         byte [] keyBytes = decryptBASE64(key);
 
         // 取得私钥
         PKCS8EncodedKeySpec pkcs8KeySpec =  new  PKCS8EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
         Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
 
         // 对数据加密
         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 keyPairGen = KeyPairGenerator
                 .getInstance(KEY_ALGORITHM);
         keyPairGen.initialize( 1024 );
 
         KeyPair keyPair = keyPairGen.generateKeyPair();
 
         // 公钥
         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
 
         // 私钥
         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
 
         Map<String, Object> keyMap =  new  HashMap<String, Object>( 2 );
 
         keyMap.put(PUBLIC_KEY, publicKey);
         keyMap.put(PRIVATE_KEY, privateKey);
         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
import  static  org.junit.Assert.*;
 
import  org.junit.Before;
import  org.junit.Test;
 
import  java.util.Map;
 
/**
 
  * @author 梁栋
  * @version 1.0
  * @since 1.0
  */
public  class  RSACoderTest {
     private  String publicKey;
     private  String privateKey;
 
     @Before
     public  void  setUp()  throws  Exception {
         Map<String, Object> keyMap = RSACoder.initKey();
 
         publicKey = RSACoder.getPublicKey(keyMap);
         privateKey = RSACoder.getPrivateKey(keyMap);
         System.err.println( "公钥: \n\r"  + publicKey);
         System.err.println( "私钥: \n\r"  + privateKey);
     }
 
     @Test
     public  void  test()  throws  Exception {
         System.err.println( "公钥加密——私钥解密" );
         String inputStr =  "abc" ;
         byte [] data = inputStr.getBytes();
 
         byte [] encodedData = RSACoder.encryptByPublicKey(data, publicKey);
 
         byte [] decodedData = RSACoder.decryptByPrivateKey(encodedData,
                 privateKey);
 
         String outputStr =  new  String(decodedData);
         System.err.println( "加密前: "  + inputStr +  "\n\r"  "解密后: "  + outputStr);
         assertEquals(inputStr, outputStr);
 
     }
 
     @Test
     public  void  testSign()  throws  Exception {
         System.err.println( "私钥加密——公钥解密" );
         String inputStr =  "sign" ;
         byte [] data = inputStr.getBytes();
 
         byte [] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
 
         byte [] decodedData = RSACoder
                 .decryptByPublicKey(encodedData, publicKey);
 
         String outputStr =  new  String(decodedData);
         System.err.println( "加密前: "  + inputStr +  "\n\r"  "解密后: "  + outputStr);
         assertEquals(inputStr, outputStr);
 
         System.err.println( "私钥签名——公钥验证签名" );
         // 产生签名
         String sign = RSACoder.sign(encodedData, privateKey);
         System.err.println( "签名:\r"  + sign);
 
         // 验证签名
         boolean  status = RSACoder.verify(encodedData, publicKey, sign);
         System.err.println( "状态:\r"  + status);
         assertTrue(status);
 
     }
 
}


控制台输出:

公钥: 

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB

私钥: 

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmY
FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
/MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA
fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
nfpFpBJ2dw==

公钥加密——私钥解密
加密前: abc

解密后: abc
公钥: 

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB

私钥: 

MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY
j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
I2k1Afmrwyw=

私钥加密——公钥解密
加密前: sign

解密后: sign
私钥签名——公钥验证签名
签名:
ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
i3wwbYWs9wSzIf0UjlM=

状态:
true



    简要总结一下,使用公钥加密、私钥解密,完成了乙方到甲方的一次数据传递,通过私钥加密、公钥解密,同时通过私钥签名、公钥验证签名,完成了一次甲方到乙方的数据传递与验证,两次数据传递完成一整套的数据交互! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值