2

根据 PHP 的文档,bcrypt salt 是由

“$2a$”,两位数的成本参数,“$”,以及来自字母表“./0-9A-Za-z”的 22 位数字

因此,如果我使用 crypt() 函数对我的密码进行哈希处理,则结果输出包括前 7 个字符($2a$10$,如果 10 是成本参数)作为盐的一部分 - 而且,根据所有示例,我能够在互联网上找到,这个完整的输出被写入db。

我想知道将这些第一个字符与其余的盐和加密数据一起存储有什么意义。它们的含义对我来说是完全清楚的,但我真的不明白为什么这些信息应该与哈希的其余部分一起写。它们不是关于算法和计算的自适应成本的“只是”信息吗?那么存储此类与应用程序相关的信息有什么好处呢?而且(即使听起来很幼稚)为什么要将它们披露给最终可以获取我的数据库的攻击者?

4

1 回答 1

11

原因是因为 crypt 的工作原理。它的设计使您可以执行以下操作

if ($hashedPassword == crypt($rawPassword, $hashedPassword)) {
    //Verified
}

因此,通过存储所有内容,您无需每次都重新创建盐字符串......

盐的意义不是秘密。事实上,这并不意味着要保密。它是用来衬托彩虹桌的。请记住,如果他们可以获取您的数据库,那么他们也很有可能获得其他东西,因此将盐放在其他地方并不会真正给您带来太多好处。

此外,盐也无济于事。BCrypt 被设计为 CPU-Hard,这意味着暴力破解(即使知道盐)是不切实际的。这就是为什么你有一个成本参数。所以不要担心“隐藏”盐。只要把它和密码一起保存就可以了...

更不用说如果将来你想调整你的算法会发生什么?例如,假设由于安装了更好的硬件,您想增加成本参数。如果您没有将此信息与密码一起存储,那么您存储的所有密码都将失效。这样,存储的每个密码都具有验证它所需的所有信息。这样,如果哈希是当前默认值,您可以检查有效登录,如果不是,则重新哈希并使用新的更新数据库。它可以防止与更新和改进散列方法相关的问题......

于 2011-09-08T15:36:40.257 回答