安全地散列密码 - 这么多相互矛盾的建议!
我读到了很多关于如何安全存储密码的相互矛盾的建议。我唯一确定的是不要使用MD5!我见过有人提倡使用 PHP 的 bcrypt
函数,这似乎会占用服务器的处理器。我见过提倡盐的人,也见过提倡不使用盐的人。
一切都是那么的不明朗。关于如何安全存储密码是否有真实可信的建议?
编辑:经过大量研究后,我发现 ;login: 上的一篇文章相当深入地讨论了该主题: http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf
I'm reading so much conflicting advice as to how to store passwords securely. All I know for sure is not to use MD5! I've seen people advocate using PHP's bcrypt
function, which seems like it'd hog the server's processor. I've seen advocates for salts, and advocates for not using salts.
It's all just so unclear. Is there real and credible advice as to how to store passwords securely?
Edit: After a fair amount of research, I found an article from ;login: that deals with the topic in quite some depth: http://www.usenix.org/publications/login/2004-06/pdfs/alexander.pdf
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
嗯,这有几个部分。
截至今天,我认为带有盐的 SHA1 或 SHA2 相当安全对于近的 未来。有一个名为 bcrypt 的实用程序,它使用河豚的不对称变体,并具有内置的盐和计算费用的概念 -中,可能值得一看。
编辑:我想澄清一下盐是什么,因为在 SO 和网上对它有很多误解。
盐不是什么 一个
秘密,是根据您与密码进行散列的字符串预先商定的。这是密钥,而不是盐。
什么是盐
您在散列时将盐(每个散列是唯一且不可预测的)与您的密码一起包含在内,但您还在散列的外部中包含了它的未加密副本,这样,当稍后验证哈希值时,在对其进行哈希处理之前给出测试密码时,您可以包含相同的盐,以便您可以正确地比较哈希值。
Well, there is several parts to this.
As of today I think SHA1 or SHA2 with a salt is reasonably secure for the near future. There is a utility called bcrypt which uses an asymmetric variant of blowfish and has the concepts of salt and computational expense built-in, it might be worth checking out.
Edit: I wanted to clarify what a salt is, as there is a lot of misconception about it on SO and online.
What a Salt is not
A secret, pre-agreed upon string that you hash with the password. This is a secret key, not a salt.
What a Salt is
You include the salt (unique and unpredictable per hash) along with your password when hashing, but you also include a unencrypted copy of it outside of your hash, so that when verifying the hash later you are able to include the same salt when given a test password before hashing it so you can properly compare the hash.
bycrpt
的要点是< em>占用处理器! (相对而言。)正是由于这个原因,它对于密码散列来说比 SHA1/2 “更好”。 (这个“更好”假设密码散列已经掌握在攻击者手中或以其他方式暴露;如果不是这样的话那就太好了,即使是大公司也有安全妥协。)这个要求是明确考虑的>bcrypt——如果你每秒只能处理 1k 哈希值(不过,这仍然是大量的登录尝试),那么攻击者需要多长时间才能进行暴力破解?比他们每秒处理 1000 万个哈希值要长得多!暴力破解的目标攻击空间仅是允许的密码输入,通常要小得多——尤其是。在实践中使用“简单密码”——比哈希空间!
并且非常需要盐来避免以时间换取空间的彩虹表:)实际上需要为每个独特的盐值创建彩虹表。(因此,盐值越独特,需要更多空间,并且具有足够的值,这对于攻击者来说变得不切实际。)
快乐编码。
The point of
bycrpt
is to hog the processor! (Relatively speaking.) It is for this reason that it is "better" for password hashing than SHA1/2. (This "better" assumes that the password hashes are already in the hands of the attacker or otherwise exposed; while it would nice if it were not the case, even big corporations have had security compromises.)This requirement was explicitly considered for
bcrypt
-- if you can only process 1k hashes a second (still, that's a good bit of log-in attempts), how long will that take an attacker to brute-force? A good bit longer than if they could process 10 million hashes a second! The target attack space of a brute-force that is only of the allowed password input, which is often much smaller -- esp. in practice with "simple passwords" -- than the space of the hash!And a salt is very much required to avoid rainbow tables which trade time for space :) A rainbow table would effectively need to be created for each unique salt value. (Thus, the more unique salt values, the more space is required and with enough values this becomes impractical for an attacker.)
Happy coding.
首先你需要使用一个好的哈希函数,我建议SHA-256。您可以像这样创建 SHA-256 哈希:
此外,您还可以像这样使用加盐:
此外,您可以使用 HMAC,像这样:
创建可靠哈希的最佳方法是通过加盐和迭代。
您应该循环上述函数,直到散列需要 200 毫秒。
您也可以继续使用加密,但在大多数情况下这有点矫枉过正。
First of all you need to use a good hash function, I suggest SHA-256. You can create a SHA-256 hash like this:
In addition you could also use salting like this:
Moreover, you can use HMACs, like this:
The best way to create solid hashes is through salting and iteration.
You should loop the above functions until hashing takes 200ms.
You could also go ahead and use encryption, but that would be a bit overkill for most situations.
这与这个问题类似:Methods for Storage Login information in Database
可靠的建议:永远不要以明文形式存储密码!
除此之外,您还可以做出一些选择。正如我在回答链接问题时提到的,有两个阵营:让其他人存储您的身份验证数据或自己做。如果您决定自己做,那么您需要制定一个哈希例程。这可能应该包括对您的密码进行加盐处理。
This is similar to this question: Methods for storing login information in database
Credible advice: Never store your passwords in clear text!
Beyond that you have some choices to make. As I mentioned in the response to the linked question, there are two camps: let some else store your authentication data or do it your self. If you decide to do it your self, then you need to come up with a hashing routine. This should probably include a salting your passwords.
您可以使用 sha256。最好的做法是向密码添加额外信息,例如用户名、用户 ID 或其他一些数据。这样,如果有人破解您的数据库,将无法使用现有的哈希数据库来查找密码。他们必须从零开始破解密码。
You can use sha256. A good thing to do is to add extra information to the password such as username, userid, or some other data to it. This way, if someone hack your database, it will be impossible to use an existant hash database to find the password. They will have to crack the password starting from zero.