Java Cookie安全案例详解
不安全的Cookie设置案例
❌ 错误示例1:未设置安全标志
// 不安全的做法 - 生产环境中应避免
Cookie cookie = new Cookie("sessionId", "abc123");
cookie.setMaxAge(3600 * 24 * 30); // 30天过期
response.addCookie(cookie);
问题分析:

- 未设置Secure标志,允许通过HTTP传输
- 未设置HttpOnly标志,允许JavaScript访问
- 过期时间过长
- 未设置SameSite属性
❌ 错误示例2:敏感信息明文存储
// 极不安全 - 切勿使用
Cookie cookie = new Cookie("userInfo",
"username=admin;password=123456;role=admin");
cookie.setPath("/");
response.addCookie(cookie);
问题分析:
- 明文存储敏感信息
- 任何人都可以读取和篡改
- 不设置过期时间,成为会话Cookie
安全的Cookie配置案例
✅ 正确示例1:Session ID的安全配置
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
public class SecureCookieUtil {
public static void setSecureSessionCookie(HttpServletResponse response,
String sessionId) {
Cookie sessionCookie = new Cookie("SESSIONID", sessionId);
// 安全配置
sessionCookie.setSecure(true); // 仅HTTPS传输
sessionCookie.setHttpOnly(true); // 禁止JavaScript访问
sessionCookie.setPath("/"); // 设置作用域
// SameSite属性设置 (Servlet 4.0+)
// sessionCookie.setAttribute("SameSite", "Strict");
// 会话Cookie(不设置MaxAge,浏览器关闭即失效)
// 或者设置合理的过期时间
sessionCookie.setMaxAge(1800); // 30分钟
response.addCookie(sessionCookie);
}
}
✅ 正确示例2:使用加密的Cookie值
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class EncryptedCookieUtil {
private static final String AES_KEY = "YourSecretKey123"; // 必须16位
public static String encryptValue(String value) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(
AES_KEY.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encrypted = cipher.doFinal(value.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encrypted);
}
public static String decryptValue(String encryptedValue) throws Exception {
SecretKeySpec keySpec = new SecretKeySpec(
AES_KEY.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] decoded = Base64.getDecoder().decode(encryptedValue);
return new String(cipher.doFinal(decoded), "UTF-8");
}
public static void setEncryptedCookie(HttpServletResponse response,
String name,
String value,
int maxAge) throws Exception {
String encryptedValue = encryptValue(value);
Cookie cookie = new Cookie(name, encryptedValue);
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setMaxAge(maxAge);
cookie.setPath("/");
response.addCookie(cookie);
}
}
✅ 正确示例3:Spring Boot安全Cookie配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@Configuration
public class SessionCookieConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
// 安全配置
serializer.setCookieName("SESSIONID");
serializer.setCookiePath("/");
serializer.setUseSecureCookie(true); // 仅HTTPS
serializer.setUseHttpOnlyCookie(true); // 禁止JS访问
serializer.setCookieMaxAge(1800); // 30分钟过期
serializer.setSameSite("Strict"); // SameSite策略
// 域名限制
// serializer.setDomainName("example.com");
return serializer;
}
}
完整的企业级安全实现
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.UUID;
public class EnterpriseCookieManager {
private static final int SESSION_TIMEOUT = 1800; // 30分钟
private static final String COOKIE_NAME = "X-Secure-Token";
private static final SecureRandom RANDOM = new SecureRandom();
/**
* 创建安全的会话Cookie
*/
public static Cookie createSecureCookie(String userId) {
// 生成唯一的会话标识
String sessionToken = generateSessionToken();
// 创建签名的令牌
String signedToken = signToken(userId + ":" + sessionToken);
Cookie cookie = new Cookie(COOKIE_NAME, signedToken);
cookie.setSecure(true); // 仅HTTPS
cookie.setHttpOnly(true); // 禁止JS访问
cookie.setPath("/"); // 全站生效
cookie.setMaxAge(SESSION_TIMEOUT);
cookie.setDomain(".example.com"); // 设置域名范围
return cookie;
}
/**
* 验证Cookie的完整性和有效性
*/
public static boolean validateCookie(Cookie cookie) {
if (cookie == null) return false;
try {
String token = cookie.getValue();
// 验证签名
if (!verifySignature(token)) {
return false;
}
// 检查是否过期(从令牌中提取时间戳)
long timestamp = extractTimestamp(token);
if (System.currentTimeMillis() - timestamp > SESSION_TIMEOUT * 1000) {
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取安全的Cookie值
*/
public static String getSecureValue(HttpServletRequest request,
String cookieName) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName())) {
// 只处理通过HTTPS传输的Cookie
if (request.isSecure()) {
return cookie.getValue();
}
}
}
}
return null;
}
/**
* 销毁Cookie(登出时使用)
*/
public static void invalidateCookie(HttpServletResponse response) {
Cookie cookie = new Cookie(COOKIE_NAME, null);
cookie.setMaxAge(0);
cookie.setPath("/");
cookie.setSecure(true);
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
private static String generateSessionToken() {
byte[] randomBytes = new byte[32];
RANDOM.nextBytes(randomBytes);
return DatatypeConverter.printHexBinary(randomBytes);
}
private static String signToken(String token) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest((token + "secret_salt").getBytes("UTF-8"));
return token + ":" + DatatypeConverter.printHexBinary(hash);
} catch (Exception e) {
throw new RuntimeException("Token signing failed", e);
}
}
private static boolean verifySignature(String signedToken) {
try {
String[] parts = signedToken.split(":");
if (parts.length != 3) return false;
String originalToken = parts[0] + ":" + parts[1];
String expectedSignature = parts[2];
MessageDigest md = MessageDigest.getInstance("SHA-256");
String computedHash = DatatypeConverter.printHexBinary(
md.digest((originalToken + "secret_salt").getBytes("UTF-8")));
return expectedSignature.equals(computedHash);
} catch (Exception e) {
return false;
}
}
private static long extractTimestamp(String signedToken) {
// 假设令牌格式: userId:sessionToken:timestamp:signature
String[] parts = signedToken.split(":");
return Long.parseLong(parts[2]);
}
}
Web安全头配置
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/api/*")
public class SecurityHeadersFilter implements Filter {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// HSTS(HTTP严格传输安全)
httpResponse.setHeader("Strict-Transport-Security",
"max-age=31536000; includeSubDomains");
// 防止XSS攻击
httpResponse.setHeader("X-Content-Type-Options", "nosniff");
httpResponse.setHeader("X-Frame-Options", "DENY");
httpResponse.setHeader("X-XSS-Protection",
"1; mode=block");
// 控制资源加载策略
httpResponse.setHeader("Content-Security-Policy",
"default-src 'self'; script-src 'self'");
// 控制Referer信息
httpResponse.setHeader("Referrer-Policy",
"strict-origin-when-cross-origin");
// 禁止通过JavaScript访问Cookie
// 使用Set-Cookie头设置SameSite
// response.setHeader("Set-Cookie",
// "SESSIONID=xxx; Secure; HttpOnly; SameSite=Strict");
chain.doFilter(request, response);
}
}
安全最佳实践总结
| 安全措施 | 说明 | 配置方式 |
|---|---|---|
| Secure | 仅HTTPS传输 | cookie.setSecure(true) |
| HttpOnly | 禁止JavaScript访问 | cookie.setHttpOnly(true) |
| SameSite | 防止CSRF攻击 | SameSite=Strict/Lax |
| 过期时间 | 限制Cookie生命周期 | setMaxAge(1800) |
| 签名验证 | 防止篡改 | HMAC或数字签名 |
| 加密 | 保护敏感数据 | AES加密存储 |
| 路径限制 | 限制作用域 | setPath("/app") |
| 域名限制 | 限制访问域名 | setDomain(".example.com") |
特别注意:
- 绝不将密码、信用卡等敏感信息存储在Cookie中
- Session ID应该在服务器端进行绑定验证
- 定期轮换密钥和会话ID
- 对Cookie值进行完整性校验
- 使用最新的Servlet规范和浏览器安全特性
案例涵盖了从基础到高级的Java Cookie安全实现,可根据实际需求选择合适的安全级别。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播