| 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  dm | 
|  * @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; | 
|     } | 
| } |