上代码:
public class AesSecretUtil {
/**
* 加密方式
*/
private static final String ALGORITHM = "AES";
/**
* keySize
*/
private static final int KEY_SIZE = 128;
/**
* 算法/模式/填充
*/
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
/**
* 初始化向量使用的数组
*/
private static final byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6};
/**
* 初始向量IV, 初始向量IV的长度规定为128位16个字节.
*/
private static final GCMParameterSpec gcMParameterSpec;
static {
gcMParameterSpec = new GCMParameterSpec(128, iv);
java.security.Security.setProperty("crypto.policy", "unlimited");
}
/**
* 加密数据
* @param key 秘钥
* @param data 需加密的明文数据
* @return 密文数据
*/
public static String encrypt(String key, String data) throws Exception {
if (StrUtil.isBlank(data)){
return StrUtil.EMPTY;
}
KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
generator.init(KEY_SIZE);
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,gcMParameterSpec);
byte[] encryptedData = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* 解密数据
* @param key 秘钥
* @param encryptedData 需解密字符串
* @return 明文数据
*/
public static String decrypt(String key, String encryptedData) throws Exception {
if (StrUtil.isBlank(encryptedData)){
return StrUtil.EMPTY;
}
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey,gcMParameterSpec);
byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedData);
}
}
这里用的初始化向量是固定的数组转换的,实际生产中,也可以使用随机数组进行加密解密,不过加密解密使用的初始化向量一定要相同。所以此时需要在数据库中存储需要加密解密数据的同时,也要存储初始化向量数据。类似于随机盐。