4 package com.sdyy.common.utils;
5
6 import java.security.Key;
7 import java.security.KeyFactory;
8 import java.security.KeyPair;
9 import java.security.KeyPairGenerator;
10 import java.security.NoSuchAlgorithmException;
11 import java.security.PrivateKey;
12 import java.security.PublicKey;
13 import java.security.SecureRandom;
14 import java.security.Signature;
15 import java.security.interfaces.RSAPrivateKey;
16 import java.security.interfaces.RSAPublicKey;
17 import java.security.spec.InvalidKeySpecException;
18 import java.security.spec.PKCS8EncodedKeySpec;
19 import java.security.spec.X509EncodedKeySpec;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.zip.CRC32;
23
24 import javax.crypto.Cipher;
25 import javax.crypto.KeyGenerator;
26 import javax.crypto.NoSuchPaddingException;
27 import javax.crypto.SecretKey;
28 import javax.crypto.spec.SecretKeySpec;
29
30 import org.apache.commons.codec.binary.Base64;
31
32 /**
33 * @ClassName: EncryptUtils
34 * @Description: 加密、解密、压缩工具
35 * @author: liuyx
36 * @date: 2016年5月10日上午9:07:42
37 */
38 public class EncryptUtils extends Base64 {
39 public static final String KEY_ALGORITHM_RSA = "RSA";
40 public static final String KEY_ALGORITHM_AES = "AES";
41
42 private static final String PUBLIC_KEY = "RSAPublicKey";
43 private static final String PRIVATE_KEY = "RSAPrivateKey";
44
45 public static final String SIGNATURE_ALGORITHM_MD5_RSA = "MD5withRSA";
46 /**
47 *
48 * @Title: getCRC32Value
49 * @author:liuyx @date:2016年5月10日09:19:29
50 * @Description: 获取字符串对应的重复概率较小的整形
51 * @param str
52 * 传入32位字符串
53 * @return
54 */
55 public static String getCRC32Value(String str) {
56 CRC32 crc32 = new CRC32();
57 crc32.update(str.getBytes());
58 return Long.toString(crc32.getValue());
59 }
60
61 /*AES相关------start*/
62 /**
63 *
64 * @Title: getAesRandomKeyString
65 * @author:liuyx
66 * @date:2016年5月10日上午9:30:15
67 * @Description: 获取AES随机密钥字符串
68 * @return
69 */
70 public static String getAESRandomKeyString() {
71 // 随机生成密钥
72 KeyGenerator keygen;
73 try {
74 keygen = KeyGenerator.getInstance(KEY_ALGORITHM_AES);
75 SecureRandom random = new SecureRandom();
76 keygen.init(random);
77 Key key = keygen.generateKey();
78 // 获取秘钥字符串
79 String key64Str = encodeBase64String(key.getEncoded());
80 return key64Str;
81 } catch (NoSuchAlgorithmException e) {
82 // TODO Auto-generated catch block
83 // e.printStackTrace();
84 return null;
85 }
86
87 }
88
89 /**
90 *
91 * @Title: encryptByAESAndBase64
92 * @author:liuyx
93 * @date:2016年5月10日上午9:40:37
94 * @Description: 使用AES加密,并返回经过BASE64处理后的密文
95 * @param base64EncodedAESKey
96 * 经过BASE64加密后的AES秘钥
97 * @param dataStr
98 * @return
99 */
100 public static String encryptByAESAndBase64(String base64EncodedAESKey, String dataStr) {
101 SecretKey secretKey = restoreAESKey(base64EncodedAESKey);
102
103 // 初始化加密组件
104 Cipher cipher;
105 try {
106 cipher = Cipher.getInstance(KEY_ALGORITHM_AES);
107 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
108 // 加密后的数据,首先将字符串转为byte数组,然后加密,为便于保存先转为base64
109 String encryptedDataStr = encodeBase64String(cipher.doFinal(dataStr.getBytes()));
110 return encryptedDataStr;
111 } catch (Exception e) {
112 // e.printStackTrace();
113 return null;
114 }
115 }
116
117 /**
118 *
119 * @Title: decryptByAESAndBase64
120 * @author:liuyx
121 * @date:2016年5月10日上午11:24:47
122 * @Description: 使用AES解密,并返回经过BASE64处理后的密文
123 * @param base64EncodedAESKey
124 * @param encryptedDataStr
125 * @return
126 */
127 public static String decryptByAESAndBase64(String base64EncodedAESKey, String encryptedDataStr) {
128 SecretKey secretKey = restoreAESKey(base64EncodedAESKey);
129 try {
130 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_AES);
131 // 将加密组件的模式改为解密
132 cipher.init(Cipher.DECRYPT_MODE, secretKey);
133 // 和上面的加密相反,先解base64,再解密,最后将byte数组转为字符串
134 String decryptedDataStr = new String(cipher.doFinal(Base64.decodeBase64(encryptedDataStr)));
135 return decryptedDataStr;
136 } catch (Exception e) {
137 // TODO: handle exception
138 return null;
139 }
140
141 }
142
143 /**
144 *
145 * @Title: restoreAESKey
146 * @author:liuyx
147 * @date:2016年5月10日上午9:53:01
148 * @Description: 还原BASE64加密后的AES密钥
149 * @param base64EncodedAESKey
150 * @return
151 */
152 public static SecretKey restoreAESKey(String base64EncodedAESKey) {
153 // 还原秘钥字符串到秘钥byte数组
154 byte[] keyByteArray = decodeBase64(base64EncodedAESKey);
155 // 重新形成秘钥,SecretKey是Key的子类
156 SecretKey secretKey = new SecretKeySpec(keyByteArray, KEY_ALGORITHM_AES);
157 return secretKey;
158 }
159
160 /*AES相关------end*/
161
162
163 /*RSA相关------start*/
164 /**
165 *
166 * @Title: getRSARandomKeyPair
167 * @author:liuyx
168 * @date:2016年5月10日上午10:00:04
169 * @Description: 生成RSA密钥对
170 * @return
171 */
172 public static Map getRSARandomKeyPair() {
173 KeyPairGenerator keyPairGen;
174 try {
175 keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM_RSA);
176 keyPairGen.initialize(512);
177 KeyPair keyPair = keyPairGen.generateKeyPair();
178 // 公钥
179 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
180 // 私钥
181 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
182
183 String publicKeyStr = encodeBase64String(publicKey.getEncoded());
184 String privateKeyStr = encodeBase64String(privateKey.getEncoded());
185
186 Map<String, String> keyMap = new HashMap<String, String>(2);
187 keyMap.put(PUBLIC_KEY, publicKeyStr);
188 keyMap.put(PRIVATE_KEY, privateKeyStr);
189 return keyMap;
190 } catch (NoSuchAlgorithmException e) {
191 //e.printStackTrace();
192 return null;
193 }
194
195 }
196
197 /**
198 *
199 * @Title: encryptByRSAPublicKeyAndBase64
200 * @author:liuyx
201 * @date:2016年5月10日上午10:50:00
202 * @Description: RSA公钥加密:使用RSA公钥(BASE64加密后的字符串)对数据进行加密
203 * @param publicRSAKey
204 * @param dataStr
205 * @return
206 */
207 public static String encryptByRSAPublicKeyAndBase64(String publicRSAKey,String dataStr) {
208 byte[] data = dataStr.getBytes();
209 // 对公钥解密
210 Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey);
211
212 // 对数据加密
213 Cipher cipher;
214 try {
215 cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
216 cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);
217 byte[] encodedData = cipher.doFinal(data);
218 String encodedDataStr = encodeBase64String(encodedData);
219 return encodedDataStr;
220 } catch (Exception e) {
221 // TODO Auto-generated catch block
222 return null;
223 }
224
225 }
226 /**
227 *
228 * @Title: decryptByRSAPublicKeyAndBase64
229 * @author:liuyx
230 * @date:2016年5月10日上午10:56:03
231 * @Description: RSA公钥解密:使用RSA公钥(BASE64加密后的字符串)对数据进行解密
232 * @param publicRSAKey
233 * @param encryptedDataStr
234 * @return
235 */
236 public static String decryptByRSAPublicKeyAndBase64(String publicRSAKey, String encryptedDataStr) {
237 //还原公钥
238 Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey);
239 try {
240 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
241 cipher.init(Cipher.DECRYPT_MODE, decodePublicKey);
242 byte[] decodedData = cipher.doFinal(Base64.decodeBase64(encryptedDataStr));
243 String decodedDataStr = new String(decodedData);
244 return decodedDataStr;
245 } catch (Exception e) {
246 // TODO: handle exception
247 return null;
248 }
249
250 }
251
252 /**
253 *
254 * @Title: getSignFromEncryptedDataWithPrivateKey
255 * @author:liuyx
256 * @date:2016年5月10日上午11:08:13
257 * @Description: 生成RSA签名:使用base64加密后的私钥和加密后的数据(byte数组形式),获取加密数据签名
258 * @param privateRSAKey
259 * @param encryotedDataStr
260 * @return
261 */
262 public static String getSignFromEncryptedDataWithPrivateKey(String privateRSAKey,String encryotedDataStr) {
263 byte[] data = decodeBase64(encryotedDataStr);
264 //加密后的数据+私钥,生成签名
265 Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);
266 Signature signature;
267 try {
268 signature = Signature.getInstance(SIGNATURE_ALGORITHM_MD5_RSA);
269 signature.initSign((PrivateKey)decodePrivateKey); //用的是私钥
270 signature.update(data); //用的是加密后的数据字节数组
271 //取得签名
272 String sign = Base64.encodeBase64String((signature.sign()));
273 return sign;
274 } catch (Exception e) {
275 // TODO Auto-generated catch block
276 e.printStackTrace();
277 return null;
278 }
279
280 }
281
282 /**
283 *
284 * @Title: verifySign
285 * @author:liuyx
286 * @date:2016年5月10日上午11:18:06
287 * @Description: 验证RSA签名
288 * @param publicRSAKey
289 * @param sign
290 * @param encryotedDataStr
291 * @return
292 */
293 public static boolean verifySign(String publicRSAKey,String sign,String encryotedDataStr) {
294 byte[] data = decodeBase64(encryotedDataStr);
295 Key decodePublicKey = restoreRSAPublicKeyFromBase64KeyEncodeStr(publicRSAKey);
296 //初始化验证签名
297 Signature signature;
298 try {
299 signature = Signature.getInstance(SIGNATURE_ALGORITHM_MD5_RSA);
300 signature.initVerify((PublicKey )decodePublicKey); //用的是公钥
301 signature.update(data); //用的是加密后的数据字节数组
302 boolean ret = signature.verify(decodeBase64(sign));
303 return ret;
304 } catch (Exception e) {
305 // TODO Auto-generated catch block
306 e.printStackTrace();
307 }
308
309 return false;
310 }
311
312 /**
313 *
314 * @Title: encryptByRSAPrivateKeyAndBase64
315 * @author:liuyx
316 * @date:2016年5月10日上午11:00:03
317 * @Description: RSA私钥加密:使用RSA私钥(BASE64加密后的字符串)对数据进行加密
318 * @param privateRSAKey
319 * @param dataStr
320 * @return
321 */
322 public static String encryptByRSAPrivateKeyAndBase64(String privateRSAKey,String dataStr) {
323 byte[] data = dataStr.getBytes();
324 // 对私钥解密
325 Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);
326
327 // 对数据加密
328 Cipher cipher;
329 try {
330 cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
331 cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey);
332 byte[] encodedData = cipher.doFinal(data);
333 String encodedDataStr = encodeBase64String(encodedData);
334 return encodedDataStr;
335 } catch (Exception e) {
336 // TODO Auto-generated catch block
337 return null;
338 }
339
340 }
341
342 /**
343 *
344 * @Title: decryptByRSAPrivateKeyAndBase64
345 * @author:liuyx
346 * @date:2016年5月10日上午11:26:44
347 * @Description: RSA私钥解密:使用RSA私钥(BASE64加密后的字符串)对数据进行解密
348 * @param privateRSAKey
349 * @param encryptedDataStr
350 * @return
351 */
352 public static String decryptByRSAPrivateKeyAndBase64(String privateRSAKey, String encryptedDataStr) {
353 //还原私钥
354 Key decodePrivateKey = restoreRSAPrivateKeyFromBase64KeyEncodeStr(privateRSAKey);
355 try {
356 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_RSA);
357 cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey);
358 byte[] decodedData = cipher.doFinal(Base64.decodeBase64(encryptedDataStr));
359 String decodedDataStr = new String(decodedData);
360 return decodedDataStr;
361 } catch (Exception e) {
362 // TODO: handle exception
363 return null;
364 }
365
366 }
367
368 /*
369 * 获取base64加密后的字符串的原始公钥
370 */
371 private static Key restoreRSAPublicKeyFromBase64KeyEncodeStr(String keyStr) {
372 byte[] keyBytes = Base64.decodeBase64(keyStr);
373 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
374 Key publicKey = null;
375 try {
376 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
377 publicKey = keyFactory.generatePublic(x509KeySpec);
378 } catch (Exception e) {
379 // TODO Auto-generated catch block
380 e.printStackTrace();
381 }
382 return publicKey;
383 }
384
385 /*
386 * 获取base64加密后的字符串的原始私钥
387 */
388 private static Key restoreRSAPrivateKeyFromBase64KeyEncodeStr(String keyStr) {
389 byte[] keyBytes = Base64.decodeBase64(keyStr);
390 // 取得私钥
391 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
392
393 Key privateKey=null;
394 try {
395 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM_RSA);
396 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
397 } catch (Exception e) {
398 // TODO Auto-generated catch block
399 e.printStackTrace();
400 }
401 return privateKey;
402 }
403 /*RSA相关------end*/
404
405 public static void main(String[] args) {
406 String str = "981hf98w7`9h5fdjk09qy56hty4gahguewqpg{}d[}]df2,,,1,4";
407 System.out.println("原字符串:"+str);
408 String aesKey = EncryptUtils.getAESRandomKeyString();
409 String aesEncryptedStr = EncryptUtils.encryptByAESAndBase64(aesKey, str);
410 System.out.println("AES加密后:"+aesEncryptedStr);
411 String aesDecryptedStr = EncryptUtils.decryptByAESAndBase64(aesKey, aesEncryptedStr);
412 System.out.println("AES解密后:"+aesDecryptedStr);
413
414 Map<String,String> keyPair = EncryptUtils.getRSARandomKeyPair();
415 String publicRSAKey = keyPair.get(EncryptUtils.PUBLIC_KEY);
416 String privateRSAKey = keyPair.get(EncryptUtils.PRIVATE_KEY);
417
418 String encryptedStr = EncryptUtils.encryptByRSAPublicKeyAndBase64(publicRSAKey, str);
419 System.out.println("公钥加密后:"+encryptedStr);
420 String decryptedStr = EncryptUtils.decryptByRSAPrivateKeyAndBase64(privateRSAKey, encryptedStr);
421 System.out.println("私钥解密后:"+decryptedStr);
422
423 encryptedStr = EncryptUtils.encryptByRSAPrivateKeyAndBase64(privateRSAKey, str);
424 System.out.println("私钥加密后:"+encryptedStr);
425
426 String sign = EncryptUtils.getSignFromEncryptedDataWithPrivateKey(privateRSAKey, encryptedStr);
427 System.out.println("签名:"+sign);
428 boolean verifyResult = EncryptUtils.verifySign(publicRSAKey, sign, encryptedStr);
429 System.out.println("签名验证结果:"+verifyResult);
430
431 decryptedStr = EncryptUtils.decryptByRSAPublicKeyAndBase64(publicRSAKey, encryptedStr);
432 System.out.println("公钥解密后:"+decryptedStr);
433 }
434 }
异常的处理都是简单的返回了null,实际使用时请自行调整异常处理。
















