RSA是一种非对称加密算法,使用RSA前先生成一对公钥和私钥。

使用公钥加密的数据可以用私钥解密,同样私钥加密的数据也可以用公钥解密,

不同之处在于,私钥加密数据的同时还可以生成一组签名,签名是用来验证数据是否在传输过程中有变动的,使用公钥、签名、以及公钥加密后的数据,就可以验证是否有变动,当然也可以不验证。

代码示例如下,两个main方法:main和main1。加密解密都是针对byte数组的,考虑到我们实际使用的时候大部分场景应该是用字符串来传递数据,所以演示代码中频繁的将byte数组化为字符串,有些byte数组不是从字符串直接转化来的,直接通过new String的方式转字符串会出现乱码,所以用到了Base64来解决这一问题。

另外,演示代码为了方便看到全过程,基本上没有抽出方法,实际使用的时候建议重构一下。

说明就到此为止,代码如下:

1 package testEncrypt;
2
3 import java.security.Key;
4 import java.security.KeyFactory;
5 import java.security.KeyPair;
6 import java.security.KeyPairGenerator;
7 import java.security.NoSuchAlgorithmException;
8 import java.security.PrivateKey;
9 import java.security.PublicKey;
10 import java.security.Signature;
11 import java.security.interfaces.RSAPrivateKey;
12 import java.security.interfaces.RSAPublicKey;
13 import java.security.spec.InvalidKeySpecException;
14 import java.security.spec.PKCS8EncodedKeySpec;
15 import java.security.spec.X509EncodedKeySpec;
16 import java.util.HashMap;
17 import java.util.Map;
18
19 import javax.crypto.Cipher;
20
21 import org.apache.commons.codec.binary.Base64;
22
23 /**
24 *
25 * @ClassName: TestRsaEncrypt
26 * @Description: TODO
27 * @author: liuyx
28 * @date: 2016年4月28日上午10:20:59
29 */
30 public class TestRsaEncrypt {
31 public static final String KEY_ALGORITHM = "RSA";
32 private static final String PUBLIC_KEY = "RSAPublicKey";
33 private static final String PRIVATE_KEY = "RSAPrivateKey";
34 public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
35 private static KeyFactory keyFactory = null;
36 static {
37 try {
38 keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
39 } catch (NoSuchAlgorithmException e) {
40 // TODO Auto-generated catch block
41 e.printStackTrace();
42 }
43 }
44 //公钥加密 私钥解密
45 public static void main(String[] args) throws Exception {
46 //生成密钥对
47
48 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
49 keyPairGen.initialize(512);
50
51 KeyPair keyPair = keyPairGen.generateKeyPair();
52
53 // 公钥
54 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
55
56 // 私钥
57 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
58
59 Map<String, Object> keyMap = new HashMap<String, Object>(2);
60
61 keyMap.put(PUBLIC_KEY, publicKey);
62 keyMap.put(PRIVATE_KEY, privateKey);
63
64 String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
65 String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
66 System.out.println("公钥:"+publicKeyStr);
67 System.out.println("私钥:"+privateKeyStr);
68
69 //数据加密过程演示
70 System.out.println("公钥加密——私钥解密");
71
72 //要加密的数据
73 String dataStr = "abcdefghhhhhhhopqrst";
74 System.out.println("要加密的数据:"+dataStr);
75 byte[] data = dataStr.getBytes();
76
77
78 // 对公钥解密
79 Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr);
80
81 // 对数据加密
82 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
83 cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);
84 byte[] encodedData = cipher.doFinal(data);
85 String encodedDataStr = Base64.encodeBase64String(encodedData);
86 System.out.println("公钥加密后的数据:"+encodedDataStr);
87
88 //对私钥解密
89 Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
90 cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey);
91 encodedData = Base64.decodeBase64(encodedDataStr);
92 byte[] decodedData = cipher.doFinal(encodedData);
93 String decodedDataStr = new String(decodedData);
94 System.out.println("私钥解密后的数据:"+decodedDataStr);
95 }
96
97 //私钥加密 公钥解密,附带签名验证过程
98 public static void main1(String[] args) throws Exception {
99 //生成密钥对
100
101 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
102 keyPairGen.initialize(512);
103
104 KeyPair keyPair = keyPairGen.generateKeyPair();
105
106 // 公钥
107 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
108
109 // 私钥
110 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
111
112 Map<String, Object> keyMap = new HashMap<String, Object>(2);
113
114 keyMap.put(PUBLIC_KEY, publicKey);
115 keyMap.put(PRIVATE_KEY, privateKey);
116
117 String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
118 String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
119 System.out.println("公钥:"+publicKeyStr);
120 System.out.println("私钥:"+privateKeyStr);
121
122 //数据加密过程演示
123 System.out.println("私钥加密——公钥解密");
124
125 //要加密的数据
126 String dataStr = "abcdefghhhhhhhopqrst1";
127 System.out.println("要加密的数据:"+dataStr);
128 byte[] data = dataStr.getBytes();
129
130 //对私钥解密
131 Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
132 //对公钥解密
133 Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr);
134
135 // 对数据加密
136 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
137 cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey);
138 byte[] encodedData = cipher.doFinal(data);
139
140 //插曲,加密后的数据+私钥,生成签名,验证签名
141 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
142 signature.initSign((PrivateKey)decodePrivateKey); //用的是私钥
143 signature.update(encodedData); //用的是加密后的数据字节数组
144
145 //取得签名
146 String sign = Base64.encodeBase64String((signature.sign()));
147
148 //初始化验证签名
149 signature = Signature.getInstance(SIGNATURE_ALGORITHM);
150 signature.initVerify((PublicKey )decodePublicKey); //用的是公钥
151 signature.update(encodedData); //用的是加密后的数据字节数组
152
153 //实际的验证过程,获取验证结果
154 boolean ret = signature.verify(Base64.decodeBase64(sign));
155 System.out.println("验证结果:"+ret);
156 //插曲结束
157
158
159 String encodedDataStr = Base64.encodeBase64String(encodedData);
160 System.out.println("私钥加密后的数据:"+encodedDataStr);
161
162
163
164 cipher.init(Cipher.DECRYPT_MODE, decodePublicKey);
165 encodedData = Base64.decodeBase64(encodedDataStr);
166 byte[] decodedData = cipher.doFinal(encodedData);
167 String decodedDataStr = new String(decodedData);
168 System.out.println("公钥解密后的数据:"+decodedDataStr);
169
170 }
171
172 /*
173 * 获取key的base64加密后的字符串
174 */
175 private static String getBase64KeyEncodeStrFromKey(Key key) {
176 return Base64.encodeBase64String(key.getEncoded());
177 }
178
179 /*
180 * 获取base64加密后的字符串的原始公钥
181 */
182 private static Key getPublicKeyFromBase64KeyEncodeStr(String keyStr) {
183 byte[] keyBytes = Base64.decodeBase64(keyStr);
184 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
185 Key publicKey = null;
186 try {
187 publicKey = keyFactory.generatePublic(x509KeySpec);
188 } catch (Exception e) {
189 // TODO Auto-generated catch block
190 e.printStackTrace();
191 }
192 return publicKey;
193 }
194
195 private static Key getPrivateKeyFromBase64KeyEncodeStr(String keyStr) {
196 byte[] keyBytes = Base64.decodeBase64(keyStr);
197 // 取得私钥
198 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
199
200 Key privateKey=null;
201 try {
202 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
203 } catch (InvalidKeySpecException e) {
204 // TODO Auto-generated catch block
205 e.printStackTrace();
206 }
207 return privateKey;
208 }
209 }