package com.jst.mdm.commons.util;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Base64;
/**
* @Author lll
* @Date 2025/7/4 9:09 (可以根据需要修改)
*/
public class EncryptionUtils {
// AES加密密钥(16/24/32字节长度)
// code + year + month + day
private static final String BASE_KEY = "iLsdbi33jkjs";
/**
* 不可逆加密 - MD5算法
*/
public static String irreversibleMd5(String input) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
// 转换为16进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1){
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
/**
* 生成符合AES规范的动态密钥
* @param employeeId 工号(如"001"或"000001")
* @param date 指定日期(null则用当前日期)
* @return 16字节(128位)AES密钥
*/
private static byte[] generateKey(String employeeId, LocalDate date) throws Exception {
// 工号标准化:补前导零至6位
String normalizedId = String.format("%06d", Integer.parseInt(employeeId));
// 日期格式化:yyyyMMdd
String dateStr = (date != null ? date : LocalDate.now())
.format(DateTimeFormatter.BASIC_ISO_DATE);
// 组合动态密钥因子
String rawKey = BASE_KEY + normalizedId + dateStr;
// 使用SHA-256生成固定长度密钥(取前16字节)
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(rawKey.getBytes(StandardCharsets.UTF_8));
// AES-128
return Arrays.copyOf(hash, 16);
}
/**
* AES加密
*/
public static String encrypt(String data, String employeeId) throws Exception {
// 默认使用当前日期
byte[] keyBytes = generateKey(employeeId, null);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
//算法/模式/填充
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
}
/**
* AES解密(需使用加密时的相同工号和日期)
*/
public static String decrypt(String encryptedData, String employeeId, LocalDate date) throws Exception {
byte[] keyBytes = generateKey(employeeId, date);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decrypted, StandardCharsets.UTF_8);
}
}