package com.doumee.core.utils; import java.nio.charset.StandardCharsets; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * AES加解密 * @author Eva.Caesar Liu * @since 2025/03/31 16:44 */ @Data @Component public class AES { // 密钥 @Value("${security.aes.key}") private String key; // 偏移量 @Value("${security.aes.iv}") private String iv; // 密钥长度 private Integer keyLen = 128; public AES() { Security.addProvider(new BouncyCastleProvider()); } /** * 加密 * * @return String */ public String encrypt(String plainText) throws SecurityException { try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");// 创建密码器 cipher.init(Cipher.ENCRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv)));// 初始化 return new Base64().encodeAsString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { throw new SecurityException("AES encrypt throw an exception", e); } } /** * 解密 * * @param cipherText 密文 * @return String */ public String decrypt(String cipherText) throws SecurityException { try { byte[] encrypted = new Base64().decode(cipherText); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); cipher.init(Cipher.DECRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv))); return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8); } catch (Exception e) { throw new SecurityException("AES decrypt throw an exception", e); } } /** * 获取AES key * * @return SecretKeySpec */ private SecretKeySpec getAESKey() { /* 使用原始密钥进行加密,要求密钥为密钥长度的倍数 */ byte[] raw = key.getBytes(StandardCharsets.UTF_8); return new SecretKeySpec(raw, "AES"); } /** * 初始化向量一直保持16位 * * @param iv 向量 * @return byte[] */ private byte[] paddingIv(String iv) { byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8); byte[] bs = new byte[keyLen / 8]; System.arraycopy(ivBytes, 0, bs, 0, ivBytes.length); return bs; } }