确定在实施随机盐时以前是否使用过密码

Determine if password has been previously used when implementing random salts

我正在尝试实施更强大的密码 hashing/storage 机制并选择最简单的方法,PHP 的 password_hash() and password_verify()

我让 PHP 按照建议生成随机盐,这一切都是有道理的。除了,我需要实施的 "strong password" 政策的一部分是拒绝用户重新使用以前使用过的密码。理论上,我可以通过存储散列密码的存档来实现这一点。当用户更改 his/her 密码时,我们会根据哈希存档检查新哈希。如果匹配,我们就知道该密码之前已被使用并拒绝它。然而,实施随机盐虽然明显更安全,但有效地使密码哈希存档变得无用。

所以,我的问题是如何在使用随机盐的同时实施此密码策略?肯定有人 运行 解决了这个问题。

要检查以前使用的密码,您的操作与检查当前密码时完全相同,随机盐不会改变任何东西。正确的是,您必须分别验证每个旧哈希值,以确保它们不相等,但这次密集计算必须仅在更改密码时进行。

要检查带有盐的散列,您需要散列及其盐,它们必须存储在一起。 password_hash() 函数会将盐包含在生成的哈希值中,因此您不必关心自己存储盐。

y$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |                     |
 |  |  |                     hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |
 |  |  salt = nOUIs5kJ7naTuTFkBy1veu (22 characters)
 |  |
 |  cost-factor = 10 = 2^10 iterations
 |
 hash-algorithm = 2y = BCrypt

password_verify() 函数也将支持旧的哈希格式,只要它们是用 crypt() 函数生成的,这是因为像算法这样的其他参数也被存储了。这使得函数 future/past-proof.