Przeglądaj źródła

refactor(util): 替换AesCryptoUtil为AESCryptoUtils统一加密工具

- 删除旧的AesCryptoUtil类,使用新的AESCryptoUtils替代- 更新ChargingUtil和ElectricTokenManager中的加密解密调用
- 保留并启用原被注释的AES加解密核心逻辑
- 引入ConnectivityConstants常量支持平台密钥配置
- 完善参数校验和异常处理机制
-优化随机密钥与初始化向量生成方法
- 添加完整的加解密测试用例验证功能正确性
wzq 1 miesiąc temu
rodzic
commit
0c2c3d189b

+ 165 - 182
src/main/java/com/zsElectric/boot/common/util/AESCryptoUtils.java

@@ -1,5 +1,7 @@
 package com.zsElectric.boot.common.util;
 
+import com.zsElectric.boot.common.constant.ConnectivityConstants;
+
 import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
@@ -15,192 +17,173 @@ import static com.zsElectric.boot.common.constant.ConnectivityConstants.*;
  */
 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 {
+        // 参数校验
+        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\":\"Sov2Gs590CLUbx4g\"}";
+            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();
+        }
     }
 }

+ 0 - 169
src/main/java/com/zsElectric/boot/common/util/electric/AesCryptoUtil.java

@@ -1,169 +0,0 @@
-package com.zsElectric.boot.common.util.electric;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.codec.binary.Base64;
-import org.springframework.stereotype.Component;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-
-/**
- * AES加解密工具类(Key和IV作为参数传入)
- * 算法:AES/CBC/PKCS5Padding
- * 密钥长度:128位(16字节)
- * 偏移量:16字节
- */
-@Slf4j
-@Component
-public class AesCryptoUtil {
-
-    // AES加密算法/模式/填充方式[1,4](@ref)
-    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
-    private static final String AES = "AES";
-
-    /**
-     * AES加密
-     * @param content 待加密内容
-     * @param key 密钥(16字节)
-     * @param iv 偏移量(16字节)
-     * @return Base64编码的加密结果
-     */
-    public static String encrypt(String content, String key, String iv) {
-        return encrypt(content, key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * AES加密(字节数组参数)
-     * @param content 待加密内容
-     * @param key 密钥字节数组(16字节)
-     * @param iv 偏移量字节数组(16字节)
-     * @return Base64编码的加密结果
-     */
-    public static String encrypt(String content, byte[] key, byte[] iv) {
-        try {
-            // 参数校验[2](@ref)
-            validateKeyAndIv(key, iv);
-            
-            // 创建密钥和偏移量规范[4](@ref)
-            SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES);
-            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-            
-            // 初始化加密器[1](@ref)
-            Cipher cipher = Cipher.getInstance(ALGORITHM);
-            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
-            
-            // 执行加密[5](@ref)
-            byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
-            
-            // Base64编码返回
-            return Base64.encodeBase64String(encrypted);
-            
-        } catch (Exception e) {
-            log.error("AES加密失败: {}", e.getMessage(), e);
-            throw new RuntimeException("加密失败: " + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * AES解密
-     * @param encryptedContent Base64编码的加密内容
-     * @param key 密钥(16字节)
-     * @param iv 偏移量(16字节)
-     * @return 解密后的原始内容
-     */
-    public static String decrypt(String encryptedContent, String key, String iv) {
-        return decrypt(encryptedContent, key.getBytes(StandardCharsets.UTF_8), iv.getBytes(StandardCharsets.UTF_8));
-    }
-
-    /**
-     * AES解密(字节数组参数)
-     * @param encryptedContent Base64编码的加密内容
-     * @param key 密钥字节数组(16字节)
-     * @param iv 偏移量字节数组(16字节)
-     * @return 解密后的原始内容
-     */
-    public static String decrypt(String encryptedContent, byte[] key, byte[] iv) {
-        try {
-            // 参数校验
-            validateKeyAndIv(key, iv);
-            
-            // 创建密钥和偏移量规范[4](@ref)
-            SecretKeySpec secretKeySpec = new SecretKeySpec(key, AES);
-            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
-            
-            // 初始化解密器[1](@ref)
-            Cipher cipher = Cipher.getInstance(ALGORITHM);
-            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
-            
-            // Base64解码并解密[5](@ref)
-            byte[] encryptedBytes = Base64.decodeBase64(encryptedContent);
-            byte[] decrypted = cipher.doFinal(encryptedBytes);
-            
-            return new String(decrypted, StandardCharsets.UTF_8);
-            
-        } catch (Exception e) {
-            log.error("AES解密失败: {}", e.getMessage(), e);
-            throw new RuntimeException("解密失败: " + e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 验证密钥和偏移量是否符合要求[2](@ref)
-     */
-    private static void validateKeyAndIv(byte[] key, byte[] iv) {
-        if (key == null || (key.length != 16 && key.length != 24 && key.length != 32)) {
-            throw new IllegalArgumentException("密钥长度必须为16、24或32字节");
-        }
-        if (iv == null || iv.length != 16) {
-            throw new IllegalArgumentException("偏移量必须为16字节");
-        }
-    }
-
-    /**
-     * 生成随机密钥(16/24/32字节)[5](@ref)
-     */
-    public static byte[] generateRandomKey(int keySize) {
-        if (keySize != 16 && keySize != 24 && keySize != 32) {
-            throw new IllegalArgumentException("密钥长度必须是16、24或32字节");
-        }
-        byte[] key = new byte[keySize];
-        new SecureRandom().nextBytes(key);
-        return key;
-    }
-
-    /**
-     * 生成随机偏移量(16字节)[5](@ref)
-     */
-    public static byte[] generateRandomIv() {
-        byte[] iv = new byte[16];
-        new SecureRandom().nextBytes(iv);
-        return iv;
-    }
-
-    /**
-     * 将字节数组转换为十六进制字符串(用于调试和存储)
-     */
-    public static String bytesToHex(byte[] bytes) {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(String.format("%02x", b));
-        }
-        return sb.toString();
-    }
-
-    /**
-     * 将十六进制字符串转换为字节数组
-     */
-    public static byte[] hexToBytes(String hexString) {
-        int len = hexString.length();
-        byte[] data = new byte[len / 2];
-        for (int i = 0; i < len; i += 2) {
-            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
-                    + Character.digit(hexString.charAt(i + 1), 16));
-        }
-        return data;
-    }
-}

+ 2 - 2
src/main/java/com/zsElectric/boot/common/util/electric/ChargingUtil.java

@@ -43,7 +43,7 @@ public class ChargingUtil {
 
             requestParms
                     .setOperatorID(ConnectivityConstants.OPERATOR_ID)
-                    .setData(AesCryptoUtil.encrypt(queryParms.toString(),ConnectivityConstants.PLATFORM_DATA_SECRET,
+                    .setData(AESCryptoUtils.encrypt(queryParms.toString(),ConnectivityConstants.PLATFORM_DATA_SECRET,
                             ConnectivityConstants.PLATFORM_DATA_SECRET_IV))
                     .setTimeStamp(result.getTimestamp())
                     .setSeq(result.getSequence())
@@ -103,7 +103,7 @@ public class ChargingUtil {
                         break;
                 }
             }
-            String decodeData = AesCryptoUtil.decrypt(responseParms.getData(), ConnectivityConstants.PLATFORM_DATA_SECRET,
+            String decodeData = AESCryptoUtils.decrypt(responseParms.getData(), ConnectivityConstants.PLATFORM_DATA_SECRET,
                     ConnectivityConstants.PLATFORM_DATA_SECRET_IV);
             return gson.fromJson(decodeData, JsonObject.class);
         }catch (Exception e){

+ 2 - 2
src/main/java/com/zsElectric/boot/common/util/electric/ElectricTokenManager.java

@@ -161,7 +161,7 @@ public class ElectricTokenManager {
 
             requestParms
                     .setOperatorID(ConnectivityConstants.OPERATOR_ID)
-                    .setData(AesCryptoUtil.encrypt(queryTokenParms.toString(), ConnectivityConstants.DATA_SECRET,
+                    .setData(AESCryptoUtils.encrypt(queryTokenParms.toString(), ConnectivityConstants.DATA_SECRET,
                             ConnectivityConstants.DATA_SECRET_IV))
                     .setTimeStamp(result.getTimestamp())
                     .setSeq(result.getSequence())
@@ -205,7 +205,7 @@ public class ElectricTokenManager {
                         break;
                 }
             }
-            String decodeData = AesCryptoUtil.decrypt(responseParms.getData(), ConnectivityConstants.PLATFORM_DATA_SECRET,
+            String decodeData = AESCryptoUtils.decrypt(responseParms.getData(), ConnectivityConstants.PLATFORM_DATA_SECRET,
                     ConnectivityConstants.PLATFORM_DATA_SECRET_IV);
             QueryTokenResponseData responseData = gson.fromJson(decodeData, QueryTokenResponseData.class);