AESCryptoUtils.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package com.zsElectric.boot.common.util;
  2. import com.esotericsoftware.minlog.Log;
  3. import com.zsElectric.boot.common.constant.ConnectivityConstants;
  4. import lombok.extern.slf4j.Slf4j;
  5. import javax.crypto.Cipher;
  6. import javax.crypto.spec.IvParameterSpec;
  7. import javax.crypto.spec.SecretKeySpec;
  8. import java.nio.charset.StandardCharsets;
  9. import java.util.Base64;
  10. import static com.zsElectric.boot.common.constant.ConnectivityConstants.*;
  11. /**
  12. * AES加解密工具类
  13. * 支持AES-128-CBC-PKCS5Padding对称加解密算法
  14. * @version 1.0
  15. */
  16. @Slf4j
  17. public class AESCryptoUtils {
  18. // 加密算法/模式/填充方式
  19. private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  20. private static final String AES = "AES";
  21. private static final int IV_SIZE = 16; // 16字节
  22. /**
  23. * AES加密
  24. * @param data 待加密的明文
  25. * @param key 密钥(必须为16字节)
  26. * @param iv 初始化向量(必须为16字节)
  27. * @return Base64编码的加密结果
  28. * @throws Exception 加密异常
  29. */
  30. public static String encrypt(String data, String key, String iv) throws Exception {
  31. log.info("待加密数据:{}", data);
  32. // 参数校验
  33. if (data == null || data.isEmpty()) {
  34. throw new IllegalArgumentException("加密数据不能为空");
  35. }
  36. if (key == null || key.length() != 16) {
  37. throw new IllegalArgumentException("密钥必须为16位字符");
  38. }
  39. if (iv == null || iv.length() != IV_SIZE) {
  40. throw new IllegalArgumentException("初始化向量必须为16位字符");
  41. }
  42. try {
  43. // 创建密钥规范
  44. SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
  45. // 创建初始化向量规范
  46. IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
  47. // 获取加密实例并初始化
  48. Cipher cipher = Cipher.getInstance(ALGORITHM);
  49. cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
  50. // 执行加密
  51. byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
  52. // 返回Base64编码的加密结果
  53. return Base64.getEncoder().encodeToString(encryptedBytes);
  54. } catch (Exception e) {
  55. throw new Exception("AES加密失败: " + e.getMessage(), e);
  56. }
  57. }
  58. /**
  59. * AES解密
  60. * @param encryptedData Base64编码的加密数据
  61. * @param key 密钥(必须为16字节)
  62. * @param iv 初始化向量(必须为16字节)
  63. * @return 解密后的明文
  64. * @throws Exception 解密异常
  65. */
  66. public static String decrypt(String encryptedData, String key, String iv) throws Exception {
  67. // 参数校验
  68. if (encryptedData == null || encryptedData.isEmpty()) {
  69. throw new IllegalArgumentException("解密数据不能为空");
  70. }
  71. if (key == null || key.length() != 16) {
  72. throw new IllegalArgumentException("密钥必须为16位字符");
  73. }
  74. if (iv == null || iv.length() != 16) {
  75. throw new IllegalArgumentException("初始化向量必须为16位字符");
  76. }
  77. try {
  78. // 创建密钥规范
  79. SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
  80. // 创建初始化向量规范
  81. IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
  82. // 获取解密实例并初始化
  83. Cipher cipher = Cipher.getInstance(ALGORITHM);
  84. cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
  85. // Base64解码并执行解密
  86. byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
  87. byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
  88. // 返回解密结果
  89. return new String(decryptedBytes, StandardCharsets.UTF_8);
  90. } catch (Exception e) {
  91. throw new Exception("AES解密失败: " + e.getMessage(), e);
  92. }
  93. }
  94. /**
  95. * 生成随机密钥(16字节)
  96. * @return 16字节的随机密钥
  97. */
  98. public static String generateRandomKey() {
  99. return generateRandomString(16);
  100. }
  101. /**
  102. * 生成随机初始化向量(16字节)
  103. * @return 16字节的随机IV
  104. */
  105. public static String generateRandomIV() {
  106. return generateRandomString(16);
  107. }
  108. /**
  109. * 生成指定长度的随机字符串
  110. * @param length 字符串长度
  111. * @return 随机字符串
  112. */
  113. private static String generateRandomString(int length) {
  114. String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  115. StringBuilder sb = new StringBuilder(length);
  116. for (int i = 0; i < length; i++) {
  117. int index = (int) (characters.length() * Math.random());
  118. sb.append(characters.charAt(index));
  119. }
  120. return sb.toString();
  121. }
  122. /**
  123. * 测试方法
  124. */
  125. public static void main(String[] args) throws Exception {
  126. try {
  127. // 测试数据
  128. String originalData = "{\"OperatorID\":\"MA6DP6BE7\", \"OperatorSecret\":\"Sov2Gs590CLUbx4g\"}";
  129. String key = DATA_SECRET; // 16字节密钥
  130. String iv = DATA_SECRET_IV; // 16字节初始化向量
  131. System.out.println("=== AES-128-CBC-PKCS5Padding 加解密测试 ===");
  132. System.out.println("原始数据: " + originalData);
  133. System.out.println("密钥: " + key);
  134. System.out.println("初始化向量: " + iv);
  135. // 加密
  136. long startTime = System.currentTimeMillis();
  137. String encryptedData = encrypt(originalData, key, iv);
  138. long encryptTime = System.currentTimeMillis() - startTime;
  139. System.out.println("加密结果: " + encryptedData);
  140. System.out.println("加密耗时: " + encryptTime + "ms");
  141. // 解密
  142. startTime = System.currentTimeMillis();
  143. String decryptedData = decrypt(encryptedData, key, iv);
  144. long decryptTime = System.currentTimeMillis() - startTime;
  145. System.out.println("解密结果: " + decryptedData);
  146. System.out.println("解密耗时: " + decryptTime + "ms");
  147. // 验证加解密一致性
  148. boolean isSuccess = originalData.equals(decryptedData);
  149. System.out.println("加解密验证: " + (isSuccess ? "成功" : "失败"));
  150. // 测试随机密钥生成
  151. System.out.println("\n=== 随机密钥生成测试 ===");
  152. String randomKey = generateRandomKey();
  153. String randomIV = generateRandomIV();
  154. System.out.println("随机密钥: " + randomKey);
  155. System.out.println("随机IV: " + randomIV);
  156. // 使用随机密钥进行加解密测试
  157. String testEncrypted = encrypt("测试数据", randomKey, randomIV);
  158. String testDecrypted = decrypt(testEncrypted, randomKey, randomIV);
  159. System.out.println("随机密钥加解密测试: " + ("测试数据".equals(testDecrypted) ? "成功" : "失败"));
  160. } catch (Exception e) {
  161. e.printStackTrace();
  162. }
  163. }
  164. }