我知道 bcrypt 比其他方法更安全,但仍然会让您遇到需要加盐密码的情况!如果盐包含在哈希字符串中,则不需要将其单独存储在数据库中。每次我需要创建一个新的哈希,也就是一个新的盐时,我是否必须获取所有密码,提取盐并检查新的不存在与我的数据库密码相比?将盐直接分开存放以便于比较不是更容易吗?如果是,那么我没有得到:
- 以纯文本形式存储盐的要点
- 为什么 bcrypt 比手动使用带有加盐密码的 sha256 更安全
实际上,我不同意 Curtis Mattoon 在几件事上的回答。
当您使用 bcrypt 进行哈希时,盐直接存储在哈希中,因此您不需要单独存储它。我不确定他根本不必存储它是什么意思,因为没有盐的哈希是完全没用的。需要盐来根据哈希验证密码。
我同意这一点。如果您要更新一个密码,则无需全部更新。事实上,这是不可能的,因为您(希望)不知道任何其他用户的密码。
您无需费力就能获得独特的盐。如果是这种情况,您可以使用uniqid
,但问题是它的输出是可预测的。可预测性在密码学中是一件坏事。相反,您想要做的是使用尽可能接近随机的伪随机盐(即使用/dev/random
而不是/dev/urandom
)。如果你有 10 亿用户,你可能会得到一两个盐完全相同的用户,但说真的,这是个大问题吗?它所做的只是将某人暴力破解这两个特定密码的十亿密码的机会加倍,而且我怀疑发生冲突的可能性甚至有那么高。不要为此紧张自己。使盐是随机的,而不是唯一的。使用上次登录时间或 IP 地址之类的东西只会消除随机性。
至于 SHA512 和 Blowfish 之间的比较,请参见此处SHA512 vs. Blowfish 和 Bcrypt
这个网站似乎做了一个简单的解释,做得不错:http: //michaelwright.me/php-password-storage
快速回答:
1)你不需要储存盐。
2)如果您为每个密码使用唯一的盐,则不需要更新所有哈希值。
3)我不是加密专家,但是当您为每个用户/密码使用唯一的盐时,攻击者将不得不为每个用户使用一组不同的彩虹表。在整个站点中使用相同的盐值意味着每个用户的密码都容易受到相同哈希表的影响。在过去(无论好坏),我使用用户上次登录时间和/或上次 IP 的函数作为密码的盐值。
例如(伪代码)$password = hash(hash($_POST['password']) . hash($row['last_login']));
4) 我会推迟“为什么 bcrypt 更好?” 向更了解此类事情的人提问。这个答案可能会有所帮助:您如何在 PHP 中使用 bcrypt 对密码进行哈希处理?