bcrypt如何构建
Coda Hale的文章“如何安全地存储密码”声称:
bcrypt有防止彩虹表攻击的内置盐。
他引用这篇文章说,在OpenBSD的bcrypt
实现中:
OpenBSD通过arcfour(arc4random(3))密钥流生成128位bcrypt salt,内核采用内核从设备时序收集的随机数据。
我不明白这是如何工作的。 在我的盐概念中:
当我使用bcrypt使用Devise(Rails登录管理器)时,数据库中没有salt列,所以我很困惑。 如果盐是随机的并且不存储在任何地方,我们如何可靠地重复哈希过程?
简而言之, bcrypt如何能够内建盐 ?
这是bcrypt:
生成一个随机盐。 “成本”因素已经预先配置。 收集密码。
使用盐和成本因子从密码导出加密密钥。 用它来加密一个众所周知的字符串。 存储成本,盐和密文。 由于这三个元素具有已知长度,因此可以很容易地将它们连接起来并将它们存储在单个字段中,但可以稍后将它们分开。
当有人试图认证时,检索存储的成本和盐。 从输入密码,成本和盐中推导出一个密钥。 加密相同的着名字符串。 如果生成的密文与存储的密文相匹配,则密码匹配。
Bcrypt的运作方式与基于PBKDF2等算法的更传统方案非常相似。 主要区别是它使用派生密钥来加密已知的纯文本; 其他方案(合理地)假设密钥导出函数是不可逆的,并直接存储派生密钥。
存储在数据库中的bcrypt
“hash”可能如下所示:
$ 2A $ 10 $ vI8aWBnW3fID.ZQ4 / zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
这实际上是由“$”分隔的三个字段:
2a
标识所使用的bcrypt
算法版本。 10
是成本因素; 使用密钥派生函数的210次迭代(顺便说一句,这还不够,我推荐12或更多的代价)。 vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
是盐和密文,在修改后的Base-64中连接并编码。 前22个字符解码为盐的16字节值。 其余字符是密码文本进行比较以进行身份验证。 这个例子取自Coda Hale的ruby实现的文档。
我认为这句话应该是措辞如下:
bcrypt 在生成的哈希中嵌入了盐分以防止彩虹表攻击。
bcrypt
实用程序本身似乎不会维护盐的列表。 相反,salt是随机生成的,并附加到函数的输出中,以便稍后记住它们(根据bcrypt
的Java实现)。 换句话说,由bcrypt
生成的“散列” 不仅仅是散列。 相反,它是哈希和盐级联。