引入依赖

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bcprov-jdk15on</artifactId>
  4. <version>1.56</version>
  5. </dependency>

扩展加密(jdk8以上版本不需要)

替换jdk目录/jre/lib/security下文件(仅适用于jdk8)
jce_policy-8.zip

工具类

  1. /**
  2. * @Title: AESUtils.java
  3. * @Package com.guanhuaWang.util.AES
  4. * @Description: AES密码工具类
  5. * @author Guanhua Wang
  6. * @date 2019年1月15日16:22:57
  7. * @version V1.0
  8. */
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.apache.commons.codec.binary.Base64;
  11. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  12. import javax.crypto.Cipher;
  13. import javax.crypto.KeyGenerator;
  14. import javax.crypto.SecretKey;
  15. import javax.crypto.spec.IvParameterSpec;
  16. import javax.crypto.spec.SecretKeySpec;
  17. import java.security.Provider;
  18. import java.security.SecureRandom;
  19. import java.security.Security;
  20. import java.util.UUID;
  21. /**
  22. * @author GuanHua Wang
  23. * @ClassName: AESUtils
  24. * @Description: aes对称加密解密工具类, 注意密钥不能随机生机, 不同客户端调用可能需要考虑不同Provider,
  25. * 考虑安卓与IOS不同平台复杂度,简化不使用Provider
  26. * @date 2019年1月15日16:00:39
  27. */
  28. @Slf4j
  29. public class AESUtils {
  30. /***默认向量常量**/
  31. public static final String IV = "1234567890123456";
  32. /**
  33. * 使用PKCS7Padding填充必须添加一个支持PKCS7Padding的Provider
  34. * 类加载的时候就判断是否已经有支持256位的Provider,如果没有则添加进去
  35. */
  36. static {
  37. if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
  38. Security.addProvider(new BouncyCastleProvider());
  39. }
  40. }
  41. /**
  42. * 加密 128位
  43. *
  44. * @param content 需要加密的原内容
  45. * @param pkey 密匙
  46. * @return
  47. */
  48. public static byte[] aesEncrypt(String content, String pkey) {
  49. try {
  50. //SecretKey secretKey = generateKey(pkey);
  51. //byte[] enCodeFormat = secretKey.getEncoded();
  52. SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(), "AES");
  53. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// "算法/加密/填充"
  54. IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
  55. cipher.init(Cipher.ENCRYPT_MODE, skey, iv);//初始化加密器
  56. byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
  57. return encrypted; // 加密
  58. } catch (Exception e) {
  59. log.info("aesEncrypt() method error:", e);
  60. }
  61. return null;
  62. }
  63. /**
  64. * 获得密钥
  65. *
  66. * @param secretKey
  67. * @return
  68. * @throws Exception
  69. */
  70. private static SecretKey generateKey(String secretKey) throws Exception {
  71. //防止linux下 随机生成key
  72. Provider p = Security.getProvider("SUN");
  73. SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", p);
  74. secureRandom.setSeed(secretKey.getBytes());
  75. KeyGenerator kg = KeyGenerator.getInstance("AES");
  76. kg.init(secureRandom);
  77. // 生成密钥
  78. return kg.generateKey();
  79. }
  80. /**
  81. * @param content 加密前原内容
  82. * @param pkey 长度为16个字符,128位
  83. * @return base64EncodeStr aes加密完成后内容
  84. * @throws
  85. * @Title: aesEncryptStr
  86. * @Description: aes对称加密
  87. */
  88. public static String aesEncryptStr(String content, String pkey) {
  89. byte[] aesEncrypt = aesEncrypt(content, pkey);
  90. String base64EncodeStr = Base64.encodeBase64String(aesEncrypt);
  91. return base64EncodeStr;
  92. }
  93. /**
  94. * @param content base64处理过的字符串
  95. * @param pkey 密匙
  96. * @return String 返回类型
  97. * @throws Exception
  98. * @throws
  99. * @Title: aesDecodeStr
  100. * @Description: 解密 失败将返回NULL
  101. */
  102. public static String aesDecodeStr(String content, String pkey) throws Exception {
  103. try {
  104. byte[] base64DecodeStr = Base64.decodeBase64(content);
  105. byte[] aesDecode = aesDecode(base64DecodeStr, pkey);
  106. if (aesDecode == null) {
  107. return null;
  108. }
  109. String result;
  110. result = new String(aesDecode, "UTF-8");
  111. return result;
  112. } catch (Exception e) {
  113. throw new Exception("解密异常");
  114. }
  115. }
  116. /**
  117. * 解密 128位
  118. *
  119. * @param content 解密前的byte数组
  120. * @param pkey 密匙
  121. * @return result 解密后的byte数组
  122. * @throws Exception
  123. */
  124. public static byte[] aesDecode(byte[] content, String pkey) throws Exception {
  125. //SecretKey secretKey = generateKey(pkey);
  126. //byte[] enCodeFormat = secretKey.getEncoded();
  127. SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(), "AES");
  128. IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
  129. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// 创建密码器
  130. cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化解密器
  131. byte[] result = cipher.doFinal(content);
  132. return result; // 解密
  133. }
  134. /**
  135. * 生成pkey
  136. * @return
  137. */
  138. public static String genPKey(){
  139. StringBuilder stringBuilder = new StringBuilder();
  140. for (int i = 0; i < 1; i++) {
  141. stringBuilder.append(UUID.randomUUID().toString().replaceAll("-","").toUpperCase());
  142. }
  143. return stringBuilder.toString();
  144. }
  145. public static void main(String[] args) throws Exception {
  146. System.out.println(genPKey().length());
  147. //明文
  148. String content = "qq245635595";
  149. //密匙
  150. String pkey = genPKey();
  151. System.out.println("待加密报文:" + content);
  152. System.out.println("密匙:" + pkey);
  153. String aesEncryptStr = aesEncryptStr(content, pkey);
  154. System.out.println("加密报文:" + aesEncryptStr);
  155. String aesDecodeStr = aesDecodeStr(aesEncryptStr, pkey);
  156. System.out.println("解密报文:" + aesDecodeStr);
  157. System.out.println("加解密前后内容是否相等:" + aesDecodeStr.equals(content));
  158. }
  159. }