【问题标题】:Storing bcrypt hashes存储 bcrypt 哈希
【发布时间】:2011-11-13 02:51:53
【问题描述】:

根据 PHP 的文档,bcrypt salt 是由

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

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

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

【问题讨论】:

    标签: php hash crypt bcrypt password-storage


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 谢谢,ircmaxell!事实上,为什么盐必须与密码一起存储的原因对我来说已经很清楚了。我只是想知道为什么我还必须存储有关算法的信息(crypt() 输出的前 7 个字符)和成本。您回答的第二部分消除了我所有的疑虑。
    猜你喜欢
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多