考虑以下两种方法:
hashedPassword = hash(trulyRandomSalt + password)
hashedPassword和trulyRandomSalt存储在数据库中。
hashedPassword = hash(applicationConstantPepper + uniqueUserName + password)
hashedPassword和uniqueUserName存储在数据库中,applicationConstantPepper存储在应用程序配置中。这里,uniqueUserName充当盐,通常是电子邮件地址。
我已经阅读了这个question,它有很多很好的信息,但没有解决应用程序常量胡椒值以及如何使用用户名作为盐进行改进。
我一直使用方法一,使用32位加密随机盐。但是,我刚看到另一个应用程序中使用的方法二。方法二的第一个问题是它将用户名绑定到哈希值,这样用户名就永远不会改变而不重新生成哈希值。
方法二有哪些安全问题? 哪种方法最好?
答案 0 :(得分:1)
考虑以下两种方法:
第一种方法非常糟糕,因为它允许让你的哈希值的攻击者使用类似oclHashcat之类的东西来制造,通常是每月数万亿或数万亿的猜测,第二种方法是恐怖的,因为那些同样的攻击者不仅可以如果他们在获得密码之前获得applicationConstantPepper和用户名,他们可以预先计算相应的,通常是数万亿或数十亿的猜测,他们可以在获取密码时预先计算猜测。
请阅读托马斯·波尔宁所说的How to securely hash passwords?"为了使辣椒真正适用,您需要进行特殊设置,其中不仅仅是带有磁盘的PC;你需要一个HSM。"请阅读整篇文章的上下文,但要点是:
如果您还喜欢胡椒概念,请再次阅读Password Hashing add salt + pepper or is salt enough?,Thomas Porrin的答案。
答案 1 :(得分:1)
考虑以下两种方法......
两者都不是特别好......
OWASP的John Steven提供了与密码散列和存储相关的更好的写作之一。他带您了解各种威胁并解释为什么事情以某种方式完成。参见方法二有哪些安全问题?
哪种方法最好?
hashedPassword = hash(applicationConstantPepper + uniqueUserName + password)
不提供语义安全性。也就是说,使用常量胡椒和用户名,对手可以判断oracle是否回答了随机答案或真实答案。
hashedPassword = hash(trulyRandomSalt + password)
可能与其他提议的方法相当或稍微好一点。每用户随机盐具有许多理想的属性。但它也可以改进。
最后,为什么重新发明轮子?转到Openwall' Portable PHP password hashing (phpass)并使用它。它由John the Ripper的作者撰写。 Solar Designer与密码破解技术保持同步,因此该库在实践中可能非常有用。
答案 2 :(得分:1)
除了反弱密码答案之外,我想指出,(盐和胡椒)都有其目的。如果同时应用两者,则使用随机盐并将其存储在数据库中(不是原始数据库),然后使用服务器端密钥(胡椒)加密密码哈希。
我写了一篇tutorial,其中对胡椒的利弊得到了更深入的解释。即使密钥不能完全受到保护,使用服务器端密钥也是一个优势。
答案 3 :(得分:0)
两种方法大致相等,只要你使用好的哈希值就可以了(见其他答案)
使用用户名存在可以重复使用用户名的问题。如果您不包含特定于应用程序的前缀,这可能是一个很大的问题,因为用户名可能在很多地方使用,因此可能已经有一个适合该用户名的彩虹表。
“胡椒”通过要求彩虹表特定于您的应用程序来帮助缓解此问题。现在,如果用户经常更改密码,这只会成为问题,因为现在攻击者可以通过生成一个彩虹表来获取所有旧密码,而不是每次搜索只获得一个密码。在我看来,这是一个几乎可以忽略不计的缺点,因为
总的来说,从攻击者的角度来看,使用用户名作为盐的目标并没有太大的收获,如果与胡椒结合使用它们是唯一的。