Coda Hale 的文章 "How To Safely Store a Password"声称:
bcrypt has salts built-in to prevent rainbow table attacks.
他引用了this paper ,其中表示在 OpenBSD 的 bcrypt
实现中:
OpenBSD generates the 128-bit bcrypt salt from an arcfour (arc4random(3)) key stream, seeded with random data the kernel collects from device timings.
我不明白这是如何运作的。在我对盐的理解中:
- 每个存储的密码都需要不同,因此必须为每个密码生成单独的彩虹表
- 它需要存储在某个地方,以便可重复:当用户尝试登录时,我们会获取他们的密码尝试,重复我们最初存储其密码时所做的相同的盐和哈希过程,然后进行比较<
当我将 Devise(Rails 登录管理器)与 bcrypt 一起使用时,数据库中没有盐列,所以我很困惑。如果盐是随机的并且没有存储在任何地方,我们如何可靠地重复哈希过程?
简而言之,bcrypt 如何拥有内置盐?
最佳答案
这是bcrypt:
生成随机盐。 “成本”因素已预先配置。收集密码。
使用盐和成本因子从密码中派生加密 key 。用它来加密众所周知的字符串。 存储成本、盐和密文。由于这三个元素的长度已知,因此很容易将它们连接起来并将它们存储在单个字段中,并且稍后能够将它们分开。
当有人尝试进行身份验证时,检索存储的成本和盐。从输入的密码、成本和盐中派生出 key 。加密相同的众所周知的字符串。如果生成的密文与存储的密文匹配,则密码匹配。
Bcrypt 的运行方式与基于 PBKDF2 等算法的更传统方案非常相似。主要区别在于它使用派生 key 来加密已知的纯文本;其他方案(合理地)假设 key 导出函数是不可逆的,并直接存储导出的 key 。
<小时/>存储在数据库中的bcrypt
“哈希”可能如下所示:
$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
这实际上是三个字段,由“$”分隔:
2a
标识所使用的bcrypt
算法版本。10
是成本因素;使用 key 导出函数的 210 次迭代(顺便说一句,这还不够。我建议成本为 12 次或更多。)vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
是盐和密文,以修改后的 Base-64 连接和编码。前 22 个字符解码为盐的 16 字节值。其余字符为密文,用于进行身份验证比较。
关于security - bcrypt 如何具有内置盐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6832445/