java Spring安全身份验证管理漏洞
Spring文档说,记住我是通过在cookie中存储以下信息来实现的:
base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
我有以下困惑——
为什么要使用像MD5这样的不安全散列来消化信息,而不是使用SHA-1或SHA-2呢。对于这样一小部分信息来说,这些信息对性能的影响会很大吗
为什么要通过网络传输这些信息?为什么不在服务器上维护一个加密安全随机数和此信息的映射,只返回映射密钥作为cookie呢。AFAIK这是Servlet API使用的方法,被认为更安全
# 1 楼答案
让我们从第二个问题开始,因为这是一个更相关的问题:
第二个问题“为什么要通过网络传输密码……”答复:
因为你描述的只是
Simple Hash-Based Token Approach
如果你向下滚动页面Spring Security Reference: Chapter 10 Remember-Me Authentication,你会看到spring security也可以使用不同的记住我的方法:Chapter 10.3 Persistent Token Approach。这就是你在第二个问题中提出的建议
第一个问题:简短回答“对于这样一小部分信息,这些信息对性能的影响会很重要吗?”-没有
因此,如果您想使用
Simple Hash-Based Token Approach
并感觉MD5是不安全的,那么您可以将TokenBasedRememberMeService
[javadoc]子类化并重写String makeTokenSignature(long tokenExpiryTime, String username, String password)
方法。例如(未经测试)# 2 楼答案
基于简单哈希的令牌使用的MD5哈希不是该方法的漏洞
使用MD5散列密码是危险的,因为给定现有密码的散列值,可以找到另一个散列为相同值的密码(使用彩虹表)
然而,在本例中,MD5不是用来散列密码,而是用作MAC。如果您确实使用彩虹表来查找与该哈希冲突的值,那么您如何确切地使用该值
对cookie使用不同的哈希函数可能会让你感觉更安全,但在这种情况下,它不会提供更多的安全性
如果您想要更高的安全性,那么应该使用持久哈希令牌方法。简单哈希令牌以明文形式公开用户名,容易受到重播攻击。持久化令牌避免了这些问题
无论哪种方式,您都应该通过设置“记住我”cookie的“安全”和“仅限Http”标志来保护它