说明:本工具并未自己实现加密解密算法,使用jdk内置加解密工具和commons-codec工具进行加解密
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,实际使用时请自行调整异常处理。