Java实现AES加密与解密(秘钥)

Love The Way You Lie 2023-06-04 10:55 34阅读 0赞
  1. package com.company.example;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import sun.misc.BASE64Decoder;
  5. import sun.misc.BASE64Encoder;
  6. import javax.crypto.Cipher;
  7. import javax.crypto.KeyGenerator;
  8. import javax.crypto.SecretKey;
  9. import javax.crypto.spec.SecretKeySpec;
  10. import java.io.IOException;
  11. import java.security.SecureRandom;
  12. /**
  13. * AES加密解密
  14. */
  15. public class SecurityUtil {
  16. private static final Logger logger = LoggerFactory.getLogger(SecurityUtil.class);
  17. private static final String ENCODING = "UTF-8";
  18. private static final String PASSWORD = "46EBA22EF5204DD5B110A1F730513965"; // 加密秘钥
  19. /**
  20. * AES加密
  21. * @param content 明文
  22. * @return 密文
  23. */
  24. public static String encryptAES(String content) {
  25. if (StringUtil.isEmpty(content)) {
  26. throw new ParamException("明文不能为空!");
  27. }
  28. byte[] encryptResult = encrypt(content, PASSWORD);
  29. String encryptResultStr = parseByte2HexStr(encryptResult);
  30. // BASE64位加密
  31. encryptResultStr = ebotongEncrypto(encryptResultStr);
  32. return encryptResultStr;
  33. }
  34. /**
  35. * AES解密
  36. * @param encryptResultStr 密文
  37. * @return 明文
  38. */
  39. public static String decryptAES(String encryptResultStr) {
  40. if (StringUtil.isEmpty(encryptResultStr)) {
  41. throw new ParamException("密文不能为空");
  42. }
  43. // BASE64位解密
  44. try {
  45. String decrpt = ebotongDecrypto(encryptResultStr);
  46. byte[] decryptFrom = parseHexStr2Byte(decrpt);
  47. byte[] decryptResult = decrypt(decryptFrom, PASSWORD);
  48. return new String(decryptResult);
  49. } catch (Exception e) { // 当密文不规范时会报错,可忽略,但调用的地方需要考虑
  50. return null;
  51. }
  52. }
  53. /**
  54. * 加密字符串
  55. */
  56. private static String ebotongEncrypto(String str) {
  57. BASE64Encoder base64encoder = new BASE64Encoder();
  58. String result = str;
  59. if (str != null && str.length() > 0) {
  60. try {
  61. byte[] encodeByte = str.getBytes(ENCODING);
  62. result = base64encoder.encode(encodeByte);
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. // base64加密超过一定长度会自动换行 需要去除换行符
  68. return result.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
  69. }
  70. /**
  71. * 解密字符串
  72. */
  73. private static String ebotongDecrypto(String str) {
  74. BASE64Decoder base64decoder = new BASE64Decoder();
  75. try {
  76. byte[] encodeByte = base64decoder.decodeBuffer(str);
  77. return new String(encodeByte);
  78. } catch (IOException e) {
  79. logger.error("IO 异常",e);
  80. return str;
  81. }
  82. }
  83. /**
  84. * 加密
  85. * @param content 需要加密的内容
  86. * @param password 加密密码
  87. * @return
  88. */
  89. private static byte[] encrypt(String content, String password) {
  90. try {
  91. KeyGenerator kgen = KeyGenerator.getInstance("AES");
  92. // 注意这句是关键,防止linux下 随机生成key。用其他方式在Windows上正常,但Linux上会有问题
  93. SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
  94. secureRandom.setSeed(password.getBytes());
  95. kgen.init(128, secureRandom);
  96. // kgen.init(128, new SecureRandom(password.getBytes()));
  97. SecretKey secretKey = kgen.generateKey();
  98. byte[] enCodeFormat = secretKey.getEncoded();
  99. SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
  100. Cipher cipher = Cipher.getInstance("AES");// 创建密码器
  101. byte[] byteContent = content.getBytes("utf-8");
  102. cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
  103. byte[] result = cipher.doFinal(byteContent);
  104. return result; // 加密
  105. } catch (Exception e) {
  106. logger.error("加密异常", e);
  107. }
  108. return null;
  109. }
  110. /**
  111. * 解密
  112. * @param content 待解密内容
  113. * @param password 解密密钥
  114. * @return
  115. */
  116. private static byte[] decrypt(byte[] content, String password) {
  117. try {
  118. KeyGenerator kgen = KeyGenerator.getInstance("AES");
  119. // 防止linux下 随机生成key
  120. SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
  121. secureRandom.setSeed(password.getBytes());
  122. kgen.init(128, secureRandom);
  123. // kgen.init(128, new SecureRandom(password.getBytes()));
  124. SecretKey secretKey = kgen.generateKey();
  125. byte[] enCodeFormat = secretKey.getEncoded();
  126. SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
  127. Cipher cipher = Cipher.getInstance("AES");// 创建密码器
  128. cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
  129. byte[] result = cipher.doFinal(content);
  130. return result; // 加密
  131. } catch (Exception e) {
  132. logger.error("解密异常", e);
  133. }
  134. return null;
  135. }
  136. /**
  137. * 将二进制转换成16进制
  138. * @param buf
  139. * @return
  140. */
  141. private static String parseByte2HexStr(byte buf[]) {
  142. StringBuffer sb = new StringBuffer();
  143. for (int i = 0; i < buf.length; i++) {
  144. String hex = Integer.toHexString(buf[i] & 0xFF);
  145. if (hex.length() == 1) {
  146. hex = '0' + hex;
  147. }
  148. sb.append(hex.toUpperCase());
  149. }
  150. return sb.toString();
  151. }
  152. /**
  153. * 将16进制转换为二进制
  154. * @param hexStr
  155. * @return
  156. */
  157. private static byte[] parseHexStr2Byte(String hexStr) {
  158. if (hexStr.length() < 1)
  159. return null;
  160. byte[] result = new byte[hexStr.length() / 2];
  161. for (int i = 0; i < hexStr.length() / 2; i++) {
  162. int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
  163. int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
  164. result[i] = (byte) (high * 16 + low);
  165. }
  166. return result;
  167. }
  168. public static void main(String[] args) {
  169. test();
  170. }
  171. /**
  172. * 测试
  173. */
  174. private static void test() {
  175. System.out.println("加密解密试试:");
  176. String content = "EXPRESS";
  177. System.out.println("原内容为:" + content);
  178. String encryContent = encryptAES(content);
  179. System.out.println("加密后的内容为:" + encryContent);
  180. String decryContent = decryptAES(encryContent);
  181. System.out.println("解密后的内容为:" + decryContent);
  182. }
  183. }

发表评论

表情:
评论列表 (有 0 条评论,34人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java实现AES加密解密

    之前常用两种加密算法:Base64和Md5,前者容易破解,后者不可逆。 AES采用对称加密方式,破解难度非常大,在可逆的基础上,能很好的保证数据的安全性。 这里介绍Java

    相关 AES 加密解密

    java AES 加密与解密 近些年DES使用越来越少,原因就在于其使用56位密钥,比较容易被破解,近些年来逐渐被AES替代,AES已经变成目前对称加密中最流行算法之一;A