import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;
/**
* AES算法工具类
*/
public class AESUtil {
private final static Logger logger = LoggerFactory.getLogger(AESUtil.class);
/**
* 密码算法
*/
private final static String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
/**
* Key算法
*/
private final static String KEY_ALGORITHM = "AES";
/**
* 密码
*/
private static ThreadLocal<Cipher> cipherThreadLocal = new ThreadLocal<>();
private static ThreadLocal<Cipher> cipherBCThreadLocal = new ThreadLocal<>();
// static {
// Security.addProvider(new BouncyCastleProvider());
// try {
// cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
// logger.error("AESUtil produce cipher error.", e);
// cipher = null;
// }
// }
public static Cipher getCipher() {
Security.addProvider(new BouncyCastleProvider());
try {
if (cipherThreadLocal.get() == null) {
Cipher c = Cipher.getInstance(CIPHER_ALGORITHM);
cipherThreadLocal.set(c);
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
logger.error("AESUtil produce cipher error.", e);
cipherThreadLocal = null;
}
return cipherThreadLocal.get();
}
/**
* AES解密
*
* @param encryptedData 加密数据
* @param encodeKey Base64编码的Key
* @param encodeIv Base64编码的偏移量
* @return 解密后的数据
*/
public static String decrypt(String encryptedData, String encodeKey, String encodeIv) {
Cipher cipher = getCipher();
if (cipher == null) {
return null;
}
byte[] decodeData = decodeData(encryptedData);
SecretKeySpec secretKey = decodeKey(encodeKey);
IvParameterSpec ivParameter = decodeIv(encodeIv);
try {
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);
return new String(cipher.doFinal(decodeData));
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
logger.error("AESUtil decrypt data error. openId:{}, e:{}", e);
return null;
}
}
public static Cipher getCipherBC() {
Security.addProvider(new BouncyCastleProvider());
try {
if (cipherBCThreadLocal.get() == null) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
cipherBCThreadLocal.set(cipher);
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
logger.error("AESUtil produce cipher error.", e);
cipherBCThreadLocal = null;
}
return cipherBCThreadLocal.get();
}
/**
* AES解密
*
* @param encryptedData 加密数据
* @param encodeKey Base64编码的Key
* @param encodeIv Base64编码的偏移量
* @return 解密后的数据
*/
public static String decryptBC(String encryptedData, String encodeKey, String encodeIv) {
Cipher cipher = getCipherBC();
if (cipher == null) {
return null;
}
byte[] decodeData = decodeData(encryptedData);
SecretKeySpec secretKey = decodeKey(encodeKey);
IvParameterSpec ivParameter = decodeIv(encodeIv);
try {
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);
return new String(cipher.doFinal(decodeData));
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException e) {
logger.error("AESUtil decrypt data error. openId:{}, e:{}", e);
return null;
}
}
/**
* 解码数据
*
* @param encodeData 编码数据
* @return 数据
*/
private static byte[] decodeData(String encodeData) {
return Base64.getDecoder().decode(encodeData);
}
/**
* 解码Key
*
* @param encodeKey 编码Key
* @return Key
*/
private static SecretKeySpec decodeKey(String encodeKey) {
byte[] decodeKey = Base64.getDecoder().decode(encodeKey);
return new SecretKeySpec(decodeKey, KEY_ALGORITHM);
}
/**
* 解码偏移量
*
* @param encodeIv 编码偏移量
* @return 偏移量
*/
private static IvParameterSpec decodeIv(String encodeIv) {
byte[] decodeIv = Base64.getDecoder().decode(encodeIv);
return new IvParameterSpec(decodeIv);
}
}
AES解密
最新推荐文章于 2025-09-26 17:37:24 发布
本文介绍了一个AES算法工具类,该工具类使用CBC模式和PKCS7填充方式实现数据的加密和解密。提供了两种方法来获取Cipher实例,并通过示例展示了如何使用这些方法进行AES解密。
2613

被折叠的 条评论
为什么被折叠?



