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;
|
}
|
}
|