根据PHP的文档,bcrypt salt由
组成“$ 2a $”,一个两位数的成本参数,“$”,以及字母表中的22位数字“./0-9A-Za-z”
所以,如果我使用crypt()函数来哈希我的密码,结果输出包括前7个字符($ 2a $ 10 $,如果10是成本参数)作为盐的一部分 - 并且,根据我能够通过互联网找到的所有示例,这个完整的输出都写入db。
我想知道将剩下的盐和加密数据存储在第一个字符的重点是什么。它们的含义对我来说是完全清楚的,但我不能真正理解为什么这些信息应该与哈希的其余部分一起编写。它们不是关于算法的“正义”信息和计算的自适应成本吗?那么存储此类与应用程序相关的信息有什么好处?并且(即使可能听起来很幼稚)为什么要将它们披露给最终会抓住我的数据库的攻击者?
答案 0 :(得分:11)
原因是因为地穴的运作方式。它的设计使您可以执行以下操作
if ($hashedPassword == crypt($rawPassword, $hashedPassword)) {
//Verified
}
因此,通过存储所有内容,您不需要每次都重新创建salt字符串......
盐的观点不是秘密。事实上,这并不是秘密。它意味着衬托彩虹桌。记住,如果他们可以抓住你的数据库,那么他们也可以获得其他东西的机会很高,所以把盐放到其他地方并不会给你太多。
此外,盐也无济于事。 BCrypt设计为CPU-Hard,这意味着强制执行(即使知道盐)也是不切实际的。这就是为什么你有一个成本参数。所以不要担心“隐藏”盐。只需将密码存储在密码旁边就可以了......
更不用说如果将来你想要调整你的算法会发生什么?例如,假设您希望增加成本参数,因为安装了更好的硬件。如果您未使用密码存储此信息,则所有存储的密码都将无效。这样,存储的每个密码都具有验证它所需的所有信息。这样,如果哈希是当前默认值,则可以检查有效登录,如果不是,则重新哈希并使用新数据库更新数据库。它可以防止与更新和改进散列方法相关的问题......