简短回答:是的,确实如此。
长答案:没必要。
要了解为什么没有必要,我们需要查看正在比较的字符串:
$2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S
$2y$10$ILlWQrYyDJvHHkxcCgjm7OThLRAmMcTzsJOZOwjaSYiRUHq8LVYde
$2y$10$8JfydDKUNbOeiybwZ9m.j.5TC8CBqkc3RZu2DX42A4dFNpNYPWfzm
$2y$10$qeG.53lr9PVVGN4Yk.kSZuOMpfone5kINyWVpAf2gUXPseU2WdSzK
$2y$10$nZUgPUwiXIvCJ9BY1wbtbuV5vH6yff9CNyumFsI/NN2eJmf20iec.
这是相同密码的 5 个不同哈希值。格式为:
$2y$10$saltsaltsaltsaltsaltsahashhashhashhashhashhashhashhas
现在,对于远程攻击者(将运行定时攻击的人)来说,salt 是一个秘密。当我们重新哈希他们的尝试时,盐是一样的。例如:
stored password "test":
hash = $2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S
如果攻击者尝试密码“abc”,内部password_verify() 将调用crypt("abc", hash)。这将导致:
$2y$10$9JxHB8U1QKsLS/ynplKzm.FTYpGS/gNDw4SB6YD0wEtCSPgGvtPim
现在,让我们并排看一下这两个哈希:
$2y$10$9JxHB8U1QKsLS/ynplKzm.iIO7f6gtTKYA61ppVuANYxWNCA5DW1S
$2y$10$9JxHB8U1QKsLS/ynplKzm.FTYpGS/gNDw4SB6YD0wEtCSPgGvtPim
注意盐是一样的吗?请注意,直到第一个 . 之前的所有内容都是相同的。另请注意,攻击者不知道盐是什么。
如果攻击者能够对比较进行定时攻击,那就没有用了。因为他们不知道盐(因此推断哈希是什么只是浪费时间,因为没有盐他们无法确定密码)。
所以时间安全并不是绝对必要的。
那为什么要包含它呢?因为每个人都会犯错。因为纵深防御是个好主意。因为这个分析假设没有盐,散列没有任何用处(例如:如果 bcrypt 中的缺陷使散列基于密码产生偏差,所以在不知道盐的情况下,密钥空间从 72^255 减少)。
简而言之,拥有它是一件好事,但并非绝对必要......