BCrypt:如何确定两个哈希值是否指向相同的密码

17

我想知道BCrypt是如何推断输入的密码是否正确,如果每次运行生成的哈希值都不同?

示例:

假设有一个密码:"password123"

我对这个密码进行了10次哈希处理并得到了10个不同的哈希值:

$2a$10$Uw0LDj343yp1tIpouRwHGeWflT3.QjDp9DeJ2XiwTIHf1T.pjEy0i
$2a$10$uYWUCEnh4gn00w57VSrYjej.UvhzBL8Wf2doTAGSGfhUMtuGr5bha
$2a$10$cJi3XOkRxxicDjEBibNhNOg5MGM.G/.p70KE75.44ayPQo8kCDxUu
$2a$10$qLcN2obMThH544U967JM5OS0vtcfP.Iq1.f0mZdvWfyeIoWHyr422
$2a$10$5/JssXqJyGHeMQlB4pr7zebTRFSt/2iwYJHF5f7.jdlTxbH4c9Sjq
$2a$10$La1UQKu306aNWkhhfhC5XeX7mfcnfbSchBIpLG6O57gur/U/n/fua
$2a$10$xTzEGVfc1D1UHFeMO95ktOJGFT79ybKUKN.z.MidMjP1XfAeElNEi
$2a$10$i9Y.1Ix6PL1bDwoTYtC49.Y0LKpar/S5qC1SkzFB4vnafikOhHSga
$2a$10$FJNTj5xeVbIcMaf9EhodHu9jJLrJL53QHQK9OuemwMh3WuTfxXEqu
$2a$10$OXMToK5CXeNtRHC3w7eqe.Mr7p4fJanbE28E2Y3MHh6f6cq1chyE6

假设我将第一个哈希值存储在我的数据库中,几个小时后用户尝试使用正确的密码登录。生成的哈希与我在数据库中存储的哈希完全不同。

BCrypt如何确定这两个哈希是否指向相同的密码?

1个回答

21

您示例中的哈希值包含进行验证所需的所有信息:

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

你可以看到,这个字符串包含了算法、成本因素和盐。通过这些参数,您可以从登录密码计算出一个可比较的哈希值。在PHP中,您可以使用函数password_verify()来验证密码,它将自动提取成本因素和盐。

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

非常感谢!我知道它可以工作,但我想知道它是如何工作的。BCrypt从哪里获取信息,以便两个完全不同的哈希引用相同的密码。据我所知,BCrypt是一种哈希算法,因此它不允许对输出数据进行更多的推断。BCrypt如何匹配这些哈希值? - Tunguska
1
现在我明白为什么这个方法可行:盐值会影响生成的哈希值。在“解码”时,BCrypt可以检查两个哈希值是否匹配,因为有来自POST请求的明文密码信息、算法、成本因素和盐值,可以确定这两个哈希值是否指向同一个密码。感谢您的帮助! - Tunguska
@Tunguska - 没错,只要使用相同的参数计算哈希值,就会得到相同的哈希值。 - martinstoeckli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接