首页 文章

bcrypt怎么有内置盐?

提问于
浏览
492

Coda Hale的文章"How To Safely Store a Password"声称:

bcrypt内置了盐来防止彩虹表攻击 .

他引用this paper,其中说在OpenBSD的 bcrypt 实现中:

OpenBSD从arcfour(arc4random(3))密钥流生成128位bcrypt salt,并使用内核从设备计时收集的随机数据进行种子处理 .

我不明白这是如何工作的 . 在我的盐的概念:

  • 每个存储的密码需要不同,因此必须为每个密码表生成一个单独的彩虹表

  • 它需要存储在某处,以便它可重复:当用户尝试登录时,我们会尝试密码,重复我们最初存储密码时所做的盐和哈希过程,并进行比较

当我使用带有bcrypt的Devise(一个Rails登录管理器)时,数据库中没有salt列,所以我很困惑 . 如果盐是随机的并且没有存储在任何地方,我们如何可靠地重复散列过程?

总之, how can bcrypt have built-in salts

2 回答

  • 634

    这是bcrypt:

    生成随机盐 . 已经预先配置了“成本”因素 . 收集密码 .

    使用salt和cost因子从密码派生加密密钥 . 用它来加密一个众所周知的字符串 . 存储成本,盐和密文 . 因为这三个元素具有已知的长度,所以很容易将它们连接起来并将它们存储在单个字段中,但稍后可以将它们分开 .

    当有人尝试进行身份验证时,检索存储的成本和盐 . 从输入密码,成本和盐中获取密钥 . 加密相同的知名字符串 . 如果生成的密文与存储的密文匹配,则密码匹配 .

    Bcrypt以与基于诸如PBKDF2的算法的更传统方案非常类似的方式操作 . 主要区别在于使用派生密钥加密已知的纯文本;其他方案(合理地)假设密钥派生函数是不可逆的,并直接存储派生密钥 .


    存储在数据库中, bcrypt "hash"可能看起来像这样:

    $ 2a $ 10 $ vI8aWBnW3fID.ZQ4 / zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

    这实际上是三个字段,由“$”分隔:

    • 2a 标识所使用的 bcrypt 算法版本 .

    • 10 是成本因素;使用密钥派生函数的210次迭代(顺便说一下这是不够的 . 我建议成本为12或更多 . )

    • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa 是salt和密文,在修改后的Base-64中连接和编码 . 前22个字符解码为盐的16字节值 . 其余字符是要进行身份验证的密文 .

    此示例取自documentation for Coda Hale's ruby implementation.

  • 146

    我认为这句话应该措辞如下:

    bcrypt在生成的哈希中内置了盐,以防止彩虹表攻击 .

    bcrypt 实用程序本身似乎没有维护盐列表 . 相反,盐是随机生成的,并附加到函数的输出中,以便稍后记住它们(根据the Java implementation of bcrypt) . 换句话说, bcrypt 生成的"hash"不是 just 哈希 . 相反,它是哈希连接的哈希 and .

相关问题