小编典典

bcrypt 怎么能有内置的盐?

all

Coda Hale 的文章“如何安全地存储密码”声称:

bcrypt 内置了盐以防止彩虹表攻击。

他引用了这篇论文,其中说在
OpenBSD 的实现中bcrypt

OpenBSD 从一个 arcfour (arc4random(3)) 密钥流生成 128 位 bcrypt
salt,并使用内核从设备计时收集的随机数据播种。

我不明白这是怎么回事。在我对盐的概念中:

  • 每个存储的密码都需要不同,因此必须为每个密码生成单独的彩虹表
  • 它需要存储在某个地方以便可重复:当用户尝试登录时,我们会尝试输入他们的密码,重复我们最初存储密码时所做的相同的盐和哈希过程,然后比较

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

简而言之, bcrypt 怎么能有内置的 salts 呢?


阅读 143

收藏
2022-03-03

共1个答案

小编典典

这是 bcrypt:

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

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

当有人尝试进行身份验证时,检索存储的成本和盐。从输入的密码、成本和盐中派生出一个密钥。加密相同的众所周知的字符串。如果生成的密文与存储的密文匹配,则密码匹配。

Bcrypt 的运行方式与基于 PBKDF2
等算法的更传统方案非常相似。主要区别在于它使用派生密钥来加密已知的纯文本。其他方案(合理地)假设密钥派生函数是不可逆的,并直接存储派生密钥。


存储在数据库中的bcrypt“哈希”可能如下所示:

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

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

  • 2a标识使用的bcrypt算法版本。
  • 10是成本因素;2使用了密钥派生函数的10次迭代(顺便说一句,这还不够。我建议使用 12 次或更多的成本。)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa是盐和密文,在修改后的 Base-64 中连接和编码。前 22 个字符解码为 salt 的 16 字节值。其余字符是要进行比较以进行身份​​验证的密文。

此示例取自Coda Hale 的 ruby​​ 实现的文档。

2022-03-03