
com.github.kaizen4j.algorithm.encrypt.Aes Maven / Gradle / Ivy
package com.github.kaizen4j.algorithm.encrypt;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
/**
* AES 加密类
*
* @author liuguowen
*/
public final class Aes {
private static final String AES_DECRYPTION = "AES";
private static final String CIPHER_PADDING = "AES/GCM/NoPadding";
private static final String SHA1PRNG = "SHA1PRNG";
private static final int KEY_SIZE_128 = 128;
private static final int KEY_SIZE_192 = 192;
private static final int KEY_SIZE_256 = 256;
private Aes() {
}
/**
* 生成密钥
*
* @param keySize AES 密钥长度
* @return 二进制密钥字节数组
*/
private static byte[] getKey(int keySize) {
return getKey(keySize, StringUtils.EMPTY);
}
public static byte[] getKey128() {
return getKey(KEY_SIZE_128);
}
public static byte[] getKey128(String keyStr) {
return getKey(KEY_SIZE_128, keyStr);
}
public static byte[] getKey192() {
return getKey(KEY_SIZE_192);
}
public static byte[] getKey192(String keyStr) {
return getKey(KEY_SIZE_192, keyStr);
}
public static byte[] getKey256() {
return getKey(KEY_SIZE_256);
}
public static byte[] getKey256(String keyStr) {
return getKey(KEY_SIZE_256, keyStr);
}
/**
* 生成自定义密钥
*
* @param keySize AES 密钥长度
* @param keyString 自定义密钥字符串
* @return 二进制密钥字节数组
*/
private static byte[] getKey(int keySize, String keyString) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_DECRYPTION);
// 解决 Linux 下生成 key 不一样的问题
SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG);
secureRandom.setSeed(keyString.getBytes(StandardCharsets.UTF_8));
keyGenerator.init(keySize, secureRandom);
SecretKey secretKey = keyGenerator.generateKey();
// 获取二进制密钥编码形式
return secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 转换密钥
*
* @param keyBytes 二进制密钥
* @return 密钥 SecretKey 对象
*/
private static SecretKeySpec toSecretKey(byte[] keyBytes) {
return new SecretKeySpec(keyBytes, AES_DECRYPTION);
}
/**
* 加密数据
*
* @param data 待加密数据字符串
* @param keyBytes 密钥字节数组
* @return 加密后的数据字符串
*/
public static String encrypt(String data, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
SecretKeySpec keySpec = toSecretKey(keyBytes);
GCMParameterSpec iv = getGCMParameterSpec(keySpec);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] dataBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(dataBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static GCMParameterSpec getGCMParameterSpec(SecretKeySpec skeySpec) {
return new GCMParameterSpec(128, skeySpec.getEncoded(), 0, 16);
}
/**
* 解密数据
*
* @param data 待解密数据字符串
* @param keyBytes 密钥字节数组
* @return 解密后的数据字符串
*/
public static String decrypt(String data, byte[] keyBytes) {
try {
Cipher cipher = Cipher.getInstance(CIPHER_PADDING);
SecretKeySpec keySpec = toSecretKey(keyBytes);
GCMParameterSpec iv = getGCMParameterSpec(keySpec);
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
byte[] dataBytes = Base64.decodeBase64(data);
return new String(cipher.doFinal(dataBytes));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy