|
|
@@ -1,5 +1,9 @@
|
|
|
package com.zsElectric.boot.common.util;
|
|
|
|
|
|
+import com.esotericsoftware.minlog.Log;
|
|
|
+import com.zsElectric.boot.common.constant.ConnectivityConstants;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
import javax.crypto.Cipher;
|
|
|
import javax.crypto.spec.IvParameterSpec;
|
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
|
@@ -13,194 +17,179 @@ import static com.zsElectric.boot.common.constant.ConnectivityConstants.*;
|
|
|
* 支持AES-128-CBC-PKCS5Padding对称加解密算法
|
|
|
* @version 1.0
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
public class AESCryptoUtils {
|
|
|
|
|
|
-// // 加密算法/模式/填充方式
|
|
|
-// private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
|
|
-// private static final String AES = "AES";
|
|
|
-// private static final int IV_SIZE = 16; // 16字节
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * AES加密
|
|
|
-// * @param data 待加密的明文
|
|
|
-// * @param key 密钥(必须为16字节)
|
|
|
-// * @param iv 初始化向量(必须为16字节)
|
|
|
-// * @return Base64编码的加密结果
|
|
|
-// * @throws Exception 加密异常
|
|
|
-// */
|
|
|
-// public static String encrypt(String data, String key, String iv) throws Exception {
|
|
|
-// // 参数校验
|
|
|
-// if (data == null || data.isEmpty()) {
|
|
|
-// throw new IllegalArgumentException("加密数据不能为空");
|
|
|
-// }
|
|
|
-// if (key == null || key.length() != 16) {
|
|
|
-// throw new IllegalArgumentException("密钥必须为16位字符");
|
|
|
-// }
|
|
|
-// if (iv == null || iv.length() != IV_SIZE) {
|
|
|
-// throw new IllegalArgumentException("初始化向量必须为16位字符");
|
|
|
-// }
|
|
|
-//
|
|
|
-// try {
|
|
|
-// // 创建密钥规范
|
|
|
-// SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
|
|
|
-// // 创建初始化向量规范
|
|
|
-// IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
|
|
-//
|
|
|
-// // 获取加密实例并初始化
|
|
|
-// Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
-// cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
|
|
-//
|
|
|
-// // 执行加密
|
|
|
-// byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
|
|
-//
|
|
|
-// // 返回Base64编码的加密结果
|
|
|
-// return Base64.getEncoder().encodeToString(encryptedBytes);
|
|
|
-//
|
|
|
-// } catch (Exception e) {
|
|
|
-// throw new Exception("AES加密失败: " + e.getMessage(), e);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * AES解密
|
|
|
-// * @param encryptedData Base64编码的加密数据
|
|
|
-// * @param key 密钥(必须为16字节)
|
|
|
-// * @param iv 初始化向量(必须为16字节)
|
|
|
-// * @return 解密后的明文
|
|
|
-// * @throws Exception 解密异常
|
|
|
-// */
|
|
|
-// public static String decrypt(String encryptedData, String key, String iv) throws Exception {
|
|
|
-// // 参数校验
|
|
|
-// if (encryptedData == null || encryptedData.isEmpty()) {
|
|
|
-// throw new IllegalArgumentException("解密数据不能为空");
|
|
|
-// }
|
|
|
-// if (key == null || key.length() != 16) {
|
|
|
-// throw new IllegalArgumentException("密钥必须为16位字符");
|
|
|
-// }
|
|
|
-// if (iv == null || iv.length() != 16) {
|
|
|
-// throw new IllegalArgumentException("初始化向量必须为16位字符");
|
|
|
-// }
|
|
|
-//
|
|
|
-// try {
|
|
|
-// // 创建密钥规范
|
|
|
-// SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
|
|
|
-// // 创建初始化向量规范
|
|
|
-// IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
|
|
-//
|
|
|
-// // 获取解密实例并初始化
|
|
|
-// Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
-// cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
|
|
|
-//
|
|
|
-// // Base64解码并执行解密
|
|
|
-// byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
|
|
|
-// byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
|
|
-//
|
|
|
-// // 返回解密结果
|
|
|
-// return new String(decryptedBytes, StandardCharsets.UTF_8);
|
|
|
-//
|
|
|
-// } catch (Exception e) {
|
|
|
-// throw new Exception("AES解密失败: " + e.getMessage(), e);
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 生成随机密钥(16字节)
|
|
|
-// * @return 16字节的随机密钥
|
|
|
-// */
|
|
|
-// public static String generateRandomKey() {
|
|
|
-// return generateRandomString(16);
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 生成随机初始化向量(16字节)
|
|
|
-// * @return 16字节的随机IV
|
|
|
-// */
|
|
|
-// public static String generateRandomIV() {
|
|
|
-// return generateRandomString(16);
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 生成指定长度的随机字符串
|
|
|
-// * @param length 字符串长度
|
|
|
-// * @return 随机字符串
|
|
|
-// */
|
|
|
-// private static String generateRandomString(int length) {
|
|
|
-// String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
|
-// StringBuilder sb = new StringBuilder(length);
|
|
|
-// for (int i = 0; i < length; i++) {
|
|
|
-// int index = (int) (characters.length() * Math.random());
|
|
|
-// sb.append(characters.charAt(index));
|
|
|
-// }
|
|
|
-// return sb.toString();
|
|
|
-// }
|
|
|
+ // 加密算法/模式/填充方式
|
|
|
+ private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
|
|
|
+ private static final String AES = "AES";
|
|
|
+ private static final int IV_SIZE = 16; // 16字节
|
|
|
+
|
|
|
+ /**
|
|
|
+ * AES加密
|
|
|
+ * @param data 待加密的明文
|
|
|
+ * @param key 密钥(必须为16字节)
|
|
|
+ * @param iv 初始化向量(必须为16字节)
|
|
|
+ * @return Base64编码的加密结果
|
|
|
+ * @throws Exception 加密异常
|
|
|
+ */
|
|
|
+ public static String encrypt(String data, String key, String iv) throws Exception {
|
|
|
+
|
|
|
+ log.info("待加密数据:{}", data);
|
|
|
+
|
|
|
+ // 参数校验
|
|
|
+ if (data == null || data.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("加密数据不能为空");
|
|
|
+ }
|
|
|
+ if (key == null || key.length() != 16) {
|
|
|
+ throw new IllegalArgumentException("密钥必须为16位字符");
|
|
|
+ }
|
|
|
+ if (iv == null || iv.length() != IV_SIZE) {
|
|
|
+ throw new IllegalArgumentException("初始化向量必须为16位字符");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 创建密钥规范
|
|
|
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
|
|
|
+ // 创建初始化向量规范
|
|
|
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ // 获取加密实例并初始化
|
|
|
+ Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
|
|
|
+
|
|
|
+ // 执行加密
|
|
|
+ byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ // 返回Base64编码的加密结果
|
|
|
+ return Base64.getEncoder().encodeToString(encryptedBytes);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new Exception("AES加密失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * AES解密
|
|
|
+ * @param encryptedData Base64编码的加密数据
|
|
|
+ * @param key 密钥(必须为16字节)
|
|
|
+ * @param iv 初始化向量(必须为16字节)
|
|
|
+ * @return 解密后的明文
|
|
|
+ * @throws Exception 解密异常
|
|
|
+ */
|
|
|
+ public static String decrypt(String encryptedData, String key, String iv) throws Exception {
|
|
|
+ // 参数校验
|
|
|
+ if (encryptedData == null || encryptedData.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("解密数据不能为空");
|
|
|
+ }
|
|
|
+ if (key == null || key.length() != 16) {
|
|
|
+ throw new IllegalArgumentException("密钥必须为16位字符");
|
|
|
+ }
|
|
|
+ if (iv == null || iv.length() != 16) {
|
|
|
+ throw new IllegalArgumentException("初始化向量必须为16位字符");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 创建密钥规范
|
|
|
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
|
|
|
+ // 创建初始化向量规范
|
|
|
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ // 获取解密实例并初始化
|
|
|
+ Cipher cipher = Cipher.getInstance(ALGORITHM);
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
|
|
|
+
|
|
|
+ // Base64解码并执行解密
|
|
|
+ byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
|
|
|
+ byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
|
|
+
|
|
|
+ // 返回解密结果
|
|
|
+ return new String(decryptedBytes, StandardCharsets.UTF_8);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new Exception("AES解密失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成随机密钥(16字节)
|
|
|
+ * @return 16字节的随机密钥
|
|
|
+ */
|
|
|
+ public static String generateRandomKey() {
|
|
|
+ return generateRandomString(16);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成随机初始化向量(16字节)
|
|
|
+ * @return 16字节的随机IV
|
|
|
+ */
|
|
|
+ public static String generateRandomIV() {
|
|
|
+ return generateRandomString(16);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成指定长度的随机字符串
|
|
|
+ * @param length 字符串长度
|
|
|
+ * @return 随机字符串
|
|
|
+ */
|
|
|
+ private static String generateRandomString(int length) {
|
|
|
+ String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
|
+ StringBuilder sb = new StringBuilder(length);
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+ int index = (int) (characters.length() * Math.random());
|
|
|
+ sb.append(characters.charAt(index));
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 测试方法
|
|
|
*/
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
-// String decryptedData = decrypt("B3eJFJNOlN7ubFMoxqAxVg==",
|
|
|
-// DATA_SECRET,
|
|
|
-// DATA_SECRET_IV);
|
|
|
-// System.out.println("解密结果: " + decryptedData);
|
|
|
-// try {
|
|
|
-// // 测试数据
|
|
|
-// String originalData = "{\n" +
|
|
|
-// " \"total\": 1,\n" +
|
|
|
-// " \"stationStatusInfo\": {\n" +
|
|
|
-// " \"operationlD\": \"123456789\",\n" +
|
|
|
-// " \"stationlD\": \"111111111111111\",\n" +
|
|
|
-// " \"connectorStatusInfos\":{\"connectorD\":1,\"equipmentD\":\"10000000000000000000001\",\n" +
|
|
|
-// " \"status\":4,\n" +
|
|
|
-// " \"curentA\":0,\n" +
|
|
|
-// " \"currentB\":0,\n" +
|
|
|
-// " \"curentC\":0,\n" +
|
|
|
-// " \"voltageA\":0,\n" +
|
|
|
-// " \"voltageB\":0,\n" +
|
|
|
-// " \"voltageC\":0,\n" +
|
|
|
-// " \"soc\":10\n" +
|
|
|
-// " }\n" +
|
|
|
-// " }\n" +
|
|
|
-// "}";
|
|
|
-// String key = "1234567890abcdef"; // 16字节密钥
|
|
|
-// String iv = "1234567890abcdef"; // 16字节初始化向量
|
|
|
-//
|
|
|
-// System.out.println("=== AES-128-CBC-PKCS5Padding 加解密测试 ===");
|
|
|
-// System.out.println("原始数据: " + originalData);
|
|
|
-// System.out.println("密钥: " + key);
|
|
|
-// System.out.println("初始化向量: " + iv);
|
|
|
-//
|
|
|
-// // 加密
|
|
|
-// long startTime = System.currentTimeMillis();
|
|
|
-// String encryptedData = encrypt(originalData, key, iv);
|
|
|
-// long encryptTime = System.currentTimeMillis() - startTime;
|
|
|
-// System.out.println("加密结果: " + encryptedData);
|
|
|
-// System.out.println("加密耗时: " + encryptTime + "ms");
|
|
|
-//
|
|
|
-// // 解密
|
|
|
-// startTime = System.currentTimeMillis();
|
|
|
-// String decryptedData = decrypt(encryptedData, key, iv);
|
|
|
-// long decryptTime = System.currentTimeMillis() - startTime;
|
|
|
-// System.out.println("解密结果: " + decryptedData);
|
|
|
-// System.out.println("解密耗时: " + decryptTime + "ms");
|
|
|
-//
|
|
|
-// // 验证加解密一致性
|
|
|
-// boolean isSuccess = originalData.equals(decryptedData);
|
|
|
-// System.out.println("加解密验证: " + (isSuccess ? "成功" : "失败"));
|
|
|
-//
|
|
|
-// // 测试随机密钥生成
|
|
|
-// System.out.println("\n=== 随机密钥生成测试 ===");
|
|
|
-// String randomKey = generateRandomKey();
|
|
|
-// String randomIV = generateRandomIV();
|
|
|
-// System.out.println("随机密钥: " + randomKey);
|
|
|
-// System.out.println("随机IV: " + randomIV);
|
|
|
-//
|
|
|
-// // 使用随机密钥进行加解密测试
|
|
|
-// String testEncrypted = encrypt("测试数据", randomKey, randomIV);
|
|
|
-// String testDecrypted = decrypt(testEncrypted, randomKey, randomIV);
|
|
|
-// System.out.println("随机密钥加解密测试: " + ("测试数据".equals(testDecrypted) ? "成功" : "失败"));
|
|
|
-//
|
|
|
-// } catch (Exception e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 测试数据
|
|
|
+ String originalData = "{\"OperatorID\":\"MAA9A6L75\", \"OperatorSecret\":\"yY8GtZrjhHcwptSZ\"}";
|
|
|
+ String key = PLATFORM_DATA_SECRET; // 16字节密钥
|
|
|
+ String iv = PLATFORM_DATA_SECRET_IV; // 16字节初始化向量
|
|
|
+
|
|
|
+ System.out.println("=== AES-128-CBC-PKCS5Padding 加解密测试 ===");
|
|
|
+ System.out.println("原始数据: " + originalData);
|
|
|
+ System.out.println("密钥: " + key);
|
|
|
+ System.out.println("初始化向量: " + iv);
|
|
|
+
|
|
|
+ // 加密
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+ String encryptedData = encrypt(originalData, key, iv);
|
|
|
+ long encryptTime = System.currentTimeMillis() - startTime;
|
|
|
+ System.out.println("加密结果: " + encryptedData);
|
|
|
+ System.out.println("加密耗时: " + encryptTime + "ms");
|
|
|
+
|
|
|
+ // 解密
|
|
|
+ startTime = System.currentTimeMillis();
|
|
|
+ String decryptedData = decrypt(encryptedData, key, iv);
|
|
|
+ long decryptTime = System.currentTimeMillis() - startTime;
|
|
|
+ System.out.println("解密结果: " + decryptedData);
|
|
|
+ System.out.println("解密耗时: " + decryptTime + "ms");
|
|
|
+
|
|
|
+ // 验证加解密一致性
|
|
|
+ boolean isSuccess = originalData.equals(decryptedData);
|
|
|
+ System.out.println("加解密验证: " + (isSuccess ? "成功" : "失败"));
|
|
|
+
|
|
|
+ // 测试随机密钥生成
|
|
|
+ System.out.println("\n=== 随机密钥生成测试 ===");
|
|
|
+ String randomKey = generateRandomKey();
|
|
|
+ String randomIV = generateRandomIV();
|
|
|
+ System.out.println("随机密钥: " + randomKey);
|
|
|
+ System.out.println("随机IV: " + randomIV);
|
|
|
+
|
|
|
+ // 使用随机密钥进行加解密测试
|
|
|
+ String testEncrypted = encrypt("测试数据", randomKey, randomIV);
|
|
|
+ String testDecrypted = decrypt(testEncrypted, randomKey, randomIV);
|
|
|
+ System.out.println("随机密钥加解密测试: " + ("测试数据".equals(testDecrypted) ? "成功" : "失败"));
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
}
|
|
|
}
|