本文目录导读:

在Java中实现AES加密,通常使用javax.crypto包中的Cipher类,以下是一个完整的AES加密解密案例,包括随机生成密钥、加密字符串和解密字符串的功能。
基础AES加密解密案例
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESExample {
// 加密算法
private static final String ALGORITHM = "AES";
// 加密填充模式(AES/ECB/PKCS5Padding 是最常用模式)
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
public static void main(String[] args) throws Exception {
// 1. 生成密钥
SecretKey secretKey = generateAESKey(128);
// 2. 待加密的原文
String originalText = "Hello, 这是需要加密的敏感信息!";
System.out.println("原文:" + originalText);
// 3. 加密
String encryptedText = encrypt(originalText, secretKey);
System.out.println("密文:" + encryptedText);
// 4. 解密
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("解密后:" + decryptedText);
// 验证
System.out.println("加密解密是否成功:" + originalText.equals(decryptedText));
}
/**
* 生成AES密钥
* @param keySize 密钥长度(128, 192, 256)
* @return SecretKey对象
*/
public static SecretKey generateAESKey(int keySize) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(keySize);
return keyGenerator.generateKey();
}
/**
* 加密
* @param plainText 明文
* @param secretKey 密钥
* @return Base64编码的密文
*/
public static String encrypt(String plainText, SecretKey secretKey) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 解密
* @param encryptedText Base64编码的密文
* @param secretKey 密钥
* @return 明文
*/
public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, "UTF-8");
}
}
带IV向量的CBC模式(更安全)
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESCBCExample {
// AES/CBC/PKCS5Padding 模式更安全
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static final String ALGORITHM = "AES";
public static void main(String[] args) throws Exception {
// 生成密钥
SecretKey secretKey = generateAESKey(128);
// 生成随机IV
IvParameterSpec iv = generateIV();
String originalText = "这是需要加密的敏感信息,使用CBC模式!";
System.out.println("原文:" + originalText);
// 加密(需要同时保存密钥和IV)
String encryptedText = encrypt(originalText, secretKey, iv);
System.out.println("密文:" + encryptedText);
// 解密
String decryptedText = decrypt(encryptedText, secretKey, iv);
System.out.println("解密后:" + decryptedText);
}
/**
* 生成AES密钥
*/
public static SecretKey generateAESKey(int keySize) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(keySize);
return keyGenerator.generateKey();
}
/**
* 生成IV(初始化向量)
*/
public static IvParameterSpec generateIV() {
byte[] iv = new byte[16]; // AES块大小为128位(16字节)
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
/**
* 加密(CBC模式)
*/
public static String encrypt(String plainText, SecretKey secretKey, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
/**
* 解密(CBC模式)
*/
public static String decrypt(String encryptedText, SecretKey secretKey, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, "UTF-8");
}
}
使用固定密钥(字符串转密钥)
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
public class AESWithFixedKey {
private static final String ALGORITHM = "AES";
// ECB模式不需要IV
private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
public static void main(String[] args) throws Exception {
// 固定密钥字符串(需要16、24或32字节)
String keyString = "ThisIsASecretKey1234567890"; // 24字节
// 将字符串转换为密钥
SecretKeySpec secretKey = new SecretKeySpec(keyString.getBytes("UTF-8"), ALGORITHM);
String originalText = "使用固定密钥进行AES加密!";
System.out.println("原文:" + originalText);
// 加密
String encryptedText = encrypt(originalText, secretKey);
System.out.println("密文:" + encryptedText);
// 解密
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("解密后:" + decryptedText);
}
public static String encrypt(String plainText, SecretKeySpec secretKey) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encryptedText, SecretKeySpec secretKey) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, "UTF-8");
}
}
完整工具类(推荐使用)
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESUtils {
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static final int KEY_SIZE = 128;
/**
* 生成密钥
*/
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(KEY_SIZE);
return keyGenerator.generateKey();
}
/**
* 生成IV
*/
public static IvParameterSpec generateIV() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
/**
* 加密(返回Base64编码)
*/
public static String encrypt(String plainText, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encrypted);
}
/**
* 解密
*/
public static String decrypt(String encryptedText, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decrypted, "UTF-8");
}
/**
* 将密钥转换为Base64字符串
*/
public static String keyToString(SecretKey key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
}
/**
* 将Base64字符串转换为密钥
*/
public static SecretKey stringToKey(String keyStr) {
byte[] decodedKey = Base64.getDecoder().decode(keyStr);
return new SecretKeySpec(decodedKey, 0, decodedKey.length, ALGORITHM);
}
/**
* 将IV转换为Base64字符串
*/
public static String ivToString(IvParameterSpec iv) {
return Base64.getEncoder().encodeToString(iv.getIV());
}
/**
* 将Base64字符串转换为IV
*/
public static IvParameterSpec stringToIV(String ivStr) {
byte[] iv = Base64.getDecoder().decode(ivStr);
return new IvParameterSpec(iv);
}
public static void main(String[] args) throws Exception {
// 使用示例
SecretKey key = generateKey();
IvParameterSpec iv = generateIV();
String original = "测试AES加密解密功能!";
System.out.println("原文:" + original);
// 加密
String encrypted = encrypt(original, key, iv);
System.out.println("密文:" + encrypted);
// 解密
String decrypted = decrypt(encrypted, key, iv);
System.out.println("解密后:" + decrypted);
// 密钥持久化示例
String keyStr = keyToString(key);
String ivStr = ivToString(iv);
System.out.println("密钥(Base64):" + keyStr);
System.out.println("IV(Base64):" + ivStr);
// 从字符串恢复密钥和IV
SecretKey restoredKey = stringToKey(keyStr);
IvParameterSpec restoredIv = stringToIV(ivStr);
String decrypted2 = decrypt(encrypted, restoredKey, restoredIv);
System.out.println("恢复密钥解密:" + decrypted2);
}
}
注意事项
-
密钥长度:AES支持128、192、256位密钥,256位需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy文件。
-
模式选择:
- ECB模式:简单但安全性较低,相同明文生成相同密文
- CBC模式:需要IV向量,更安全,推荐使用
-
填充方式:PKCS5Padding是最常用的填充方式
-
IV向量:CBC模式下每次加密都应使用不同的随机IV,IV不需要保密,但要保存
-
密钥管理:实际应用中,密钥应安全存储,不要硬编码在代码中
-
异常处理:实际应用中应添加适当的异常处理
这样你就可以在Java中轻松实现AES加密和解密了!