bcrypt如何能够嵌入盐? [英] How can bcrypt have built-in salts?

查看:155
本文介绍了bcrypt如何能够嵌入盐?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


bcrypt含有防止彩虹表攻击的盐。


他列举了本文,其中说OpenBSD生成的 bcrypt


OpenBSD生成来自arcfour
(arc4random(3))密钥流的128位bcrypt salt,内嵌随机数据,内核
从设备计时中收集。 b
$ b

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


  • 每个存储的密码需要不同,因此必须生成一个单独的彩虹表对于每个
  • 它需要存储在某个地方,以便它是可重复的:当用户尝试登录时,我们会尝试密码,重复与我们在做什么时使用的同样的salt-and-hash过程我们最初存储他们的密码,并比较


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



总之,这是bcrypt:



生成一个随机数盐。 成本因素已经预先配置。收集密码。



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



当有人试图验证,检索存储的成本和盐。从输入密码,成本和盐中推导出一个密钥。加密相同的着名字符串。如果生成的密文与存储的密文相匹配,那么密码是匹配的。

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




存储在数据库中, bcrypt hash可能如下所示:


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

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




  • 2a 标识 bcrypt 。
  • 10 是成本因素;使用密钥派生函数的2 10 迭代(顺便说一句,这还不够,我推荐使用12或更多的代价。)

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



本示例来自 Coda Hale的ruby实现文档


Coda Hale's article "How To Safely Store a Password" claims that:

bcrypt has salts built-in to prevent rainbow table attacks.

He cites this paper, which says that in OpenBSD's implementation of 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.

I don't understand how this can work. In my conception of a salt:

  • It needs to be different for each stored password, so that a separate rainbow table would have to be generated for each
  • It needs to be stored somewhere so that it's repeatable: when a user tries to log in, we take their password attempt, repeat the same salt-and-hash procedure we did when we originally stored their password, and compare

When I'm using Devise (a Rails login manager) with bcrypt, there is no salt column in the database, so I'm confused. If the salt is random and not stored anywhere, how can we reliably repeat the hashing process?

In short, how can bcrypt have built-in salts?

解决方案

This is bcrypt:

Generate a random salt. A "cost" factor has been pre-configured. Collect a password.

Derive an encryption key from the password using the salt and cost factor. Use it to encrypt a well-known string. Store the cost, salt, and cipher text. Because these three elements have a known length, it's easy to concatenate them and store them in a single field, yet be able to split them apart later.

When someone tries to authenticate, retrieve the stored cost and salt. Derive a key from the input password, cost and salt. Encrypt the same well-known string. If the generated cipher text matches the stored cipher text, the password is a match.

Bcrypt operates in a very similar manner to more traditional schemes based on algorithms like PBKDF2. The main difference is its use of a derived key to encrypt known plain text; other schemes (reasonably) assume the key derivation function is irreversible, and store the derived key directly.


Stored in the database, a bcrypt "hash" might look something like this:

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

This is actually three fields, delimited by "$":

  • 2a identifies the bcrypt algorithm version that was used.
  • 10 is the cost factor; 210 iterations of the key derivation function are used (which is not enough, by the way. I'd recommend a cost of 12 or more.)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa is the salt and the cipher text, concatenated and encoded in a modified Base-64. The first 22 characters decode to a 16-byte value for the salt. The remaining characters are cipher text to be compared for authentication.

This example is taken from the documentation for Coda Hale's ruby implementation.

这篇关于bcrypt如何能够嵌入盐?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆