| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- 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;
- import java.nio.charset.StandardCharsets;
- import java.util.Base64;
- import static com.zsElectric.boot.common.constant.ConnectivityConstants.*;
- /**
- * AES加解密工具类
- * 支持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 {
- 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 {
- try {
- // 测试数据
- String originalData = "{\"OperatorID\":\"MA6DP6BE7\", \"OperatorSecret\":\"Sov2Gs590CLUbx4g\"}";
- String key = DATA_SECRET; // 16字节密钥
- String iv = 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();
- }
- }
- }
|