Java 加密解密完全指南:AES、RSA、Base64 实战
加密是保障数据安全的核心技术。本文介绍 Java 中常用的加密解密方法。
加密算法分类
对称加密
加密和解密使用相同密钥。
| 算法 | 密钥长度 | 特点 |
|---|---|---|
| AES | 128/192/256位 | 最常用,推荐 |
| DES | 56位 | 已不安全 |
| 3DES | 168位 | 慢,逐步淘汰 |
非对称加密
加密和解密使用不同密钥(公钥/私钥)。
| 算法 | 密钥长度 | 特点 |
|---|---|---|
| RSA | 1024-4096位 | 最常用 |
| ECC | 256位 | 更短密钥,同等安全 |
| SM2 | 256位 | 国密算法 |
AES 加密
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class AESUtil {
// 生成密钥
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
return keyGen.generateKey();
}
// AES-GCM 加密
public static String encrypt(String data, SecretKey key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] iv = new byte[12]; // GCM 推荐 12 字节 IV
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
// IV + 密文
byte[] result = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(encrypted, 0, result, iv.length, encrypted.length);
return Base64.getEncoder().encodeToString(result);
}
// AES-GCM 解密
public static String decrypt(String encryptedData, SecretKey key) throws Exception {
byte[] decoded = Base64.getDecoder().decode(encryptedData);
byte[] iv = Arrays.copyOfRange(decoded, 0, 12);
byte[] encrypted = Arrays.copyOfRange(decoded, 12, decoded.length);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted, StandardCharsets.UTF_8);
}
}
RSA 加密
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
public class RSAUtil {
// 生成密钥对
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
return keyGen.generateKeyPair();
}
// 公钥加密
public static String encrypt(String data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted);
}
// 私钥解密
public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decrypted, StandardCharsets.UTF_8);
}
}
Base64 编码
Base64 不是加密,只是编码方式。
import java.util.Base64;
// 编码
String encoded = Base64.getEncoder().encodeToString("Hello".getBytes());
// 解码
byte[] decoded = Base64.getDecoder().decode(encoded);
String result = new String(decoded);
// URL 安全的 Base64
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
// MIME Base64(每 76 字符换行)
String mime = Base64.getMimeEncoder().encodeToString(data);
加密模式对比
| 模式 | 安全性 | 特点 |
|---|---|---|
| ECB | ❌ 不安全 | 相同明文产生相同密文 |
| CBC | ✅ 安全 | 需要 IV,串行处理 |
| GCM | ✅ 最安全 | 认证加密,推荐 |
填充方式
| 填充 | 说明 |
|---|---|
| NoPadding | 不填充(数据必须是块大小的倍数) |
| PKCS5Padding | 常用填充 |
| OAEP | RSA 推荐填充 |
最佳实践
- 使用 AES-GCM:认证加密,防止篡改
- 密钥管理:使用密钥管理系统(KMS)
- 随机 IV:每次加密使用新的随机 IV
- 密钥轮换:定期更换密钥
- 使用 HTTPS:传输层加密
总结
Java 提供了完善的加密 API。对于数据加密,推荐 AES-GCM;对于密钥交换,推荐 RSA。正确使用加密技术,可以有效保障数据安全。