Java Cookie 加密指南
在 Java 中对 Cookie 进行加密是一个重要的安全实践,可以防止敏感信息被窃取或篡改,以下是几种常见的 Cookie 加密方法:

使用对称加密算法
示例代码(使用 AES 加密)
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class CookieCryptoUtil {
private static final String ALGORITHM = "AES";
private static final String SECRET_KEY = "ThisIsASecretKey"; // 16, 24 或 32 字节长度
public static String encrypt(String value) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decrypt(String encrypted) throws Exception {
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decoded = Base64.getDecoder().decode(encrypted);
byte[] decrypted = cipher.doFinal(decoded);
return new String(decrypted);
}
}
使用非对称加密算法
示例代码(使用 RSA 加密)
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class CookieRsaCryptoUtil {
private static final String ALGORITHM = "RSA";
// 生成密钥对
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
keyGen.initialize(2048);
return keyGen.generateKeyPair();
}
// 公钥加密
public static String encrypt(String value, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(value.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
// 私钥解密
public static String decrypt(String encrypted, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decoded = Base64.getDecoder().decode(encrypted);
byte[] decrypted = cipher.doFinal(decoded);
return new String(decrypted);
}
}
使用 HMAC 进行完整性验证
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class CookieHmacUtil {
private static final String ALGORITHM = "HmacSHA256";
private static final String SECRET_KEY = "ThisIsASecretKeyForHmac";
public static String generateHmac(String data) throws Exception {
Mac sha256_HMAC = Mac.getInstance(ALGORITHM);
SecretKeySpec secret_key = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
sha256_HMAC.init(secret_key);
return Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));
}
public static boolean verifyHmac(String data, String receivedHmac) throws Exception {
String calculatedHmac = generateHmac(data);
return calculatedHmac.equals(receivedHmac);
}
}
完整的 Cookie 加密与签名实现
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class SecureCookieManager {
private static final String SECRET_KEY = "ThisIsASecretKey123456";
private static final String HMAC_KEY = "ThisIsHmacSecretKey";
public static void createSecureCookie(HttpServletResponse response, String name, String value) {
try {
// 1. 加密值
String encryptedValue = CookieCryptoUtil.encrypt(value);
// 2. 生成HMAC签名
String hmac = CookieHmacUtil.generateHmac(encryptedValue);
// 3. 组合加密值和签名
String finalValue = encryptedValue + "|" + hmac;
// 4. 创建Cookie
Cookie cookie = new Cookie(name, URLEncoder.encode(finalValue, StandardCharsets.UTF_8.name()));
cookie.setHttpOnly(true);
cookie.setSecure(true); // 仅HTTPS
cookie.setPath("/");
cookie.setMaxAge(3600); // 1小时
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String readSecureCookie(HttpServletRequest request, String name) {
try {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
String value = URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8.name());
String[] parts = value.split("\\|");
if (parts.length == 2) {
String encryptedValue = parts[0];
String receivedHmac = parts[1];
// 验证HMAC
if (CookieHmacUtil.verifyHmac(encryptedValue, receivedHmac)) {
// 解密值
return CookieCryptoUtil.decrypt(encryptedValue);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
安全注意事项
- 密钥管理:不要将密钥硬编码在代码中,应该从安全的位置加载
- HTTPS:始终通过HTTPS传输Cookie
- HttpOnly和Secure标志:设置HttpOnly和Secure标志
- 密钥轮换:定期更换加密密钥
- 算法选择:使用强加密算法(如AES-256, RSA-2048)
- 输入验证:验证所有Cookie数据,防止注入攻击
替代方案
如果不想自己实现加密,可以考虑使用成熟的库如:
- Apache Commons Crypto
- Bouncy Castle
- Jasypt (Java Simplified Encryption)
这些库提供了更完善的加密实现和更安全的管理方式。

