Security bcrypt如何具有内置盐?
Coda Hale的文章声称: bcrypt内置了盐来防止彩虹表攻击 他引用了OpenBSD实现的Security bcrypt如何具有内置盐?,security,hash,internals,bcrypt,Security,Hash,Internals,Bcrypt,Coda Hale的文章声称: bcrypt内置了盐来防止彩虹表攻击 他引用了OpenBSD实现的bcrypt: OpenBSD从arcfour生成128位bcrypt盐 (arc4random(3))密钥流,在内核中播种随机数据 从设备定时收集数据 我不明白这是怎么回事。在我对盐的概念中: 每个存储的密码都需要不同,因此必须为每个密码生成一个单独的彩虹表 它需要存储在某个地方,以便可以重复:当用户尝试登录时,我们会尝试使用他们的密码,重复最初存储他们密码时的salt和hash过程,并进行比较
bcrypt
:
OpenBSD从arcfour生成128位bcrypt盐
(arc4random(3))密钥流,在内核中播种随机数据
从设备定时收集数据
我不明白这是怎么回事。在我对盐的概念中:
- 每个存储的密码都需要不同,因此必须为每个密码生成一个单独的彩虹表
- 它需要存储在某个地方,以便可以重复:当用户尝试登录时,我们会尝试使用他们的密码,重复最初存储他们密码时的salt和hash过程,并进行比较
简而言之,bcrypt怎么可能有内置的盐呢?我认为这个短语应该用如下措辞: bcrypt在生成的哈希中内置了盐,以防止彩虹表攻击
bcrypt
实用程序本身似乎没有维护盐列表。相反,盐是随机生成的,并附加到函数的输出中,以便稍后记住它们(根据)。换句话说,bcrypt
生成的“散列”不是只是散列。相反,它是哈希和连接的盐。这是bcrypt:
生成一个随机的盐。“成本”因素已预先配置。收集密码
使用salt和成本因子从密码派生加密密钥。使用它来加密已知字符串。存储成本、盐和密码文本。因为这三个元素有一个已知的长度,所以很容易将它们连接起来并存储在一个字段中,但以后可以将它们分开
当有人试图进行身份验证时,检索存储的成本和盐。从输入密码、成本和salt派生密钥。加密相同的已知字符串。如果生成的密码文本与存储的密码文本匹配,则密码是匹配的
Bcrypt的运行方式与基于PBKDF2等算法的传统方案非常相似。主要区别在于它使用派生密钥加密已知的纯文本;其他方案(合理地)假设密钥派生函数是不可逆的,并直接存储派生密钥
存储在数据库中的
bcrypt
“哈希”可能如下所示:
$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9CGLCZEIGDMVR5YUP1KOUYTA
这实际上是三个字段,由“$”分隔:
标识所使用的2a
算法版本bcrypt
是成本因素;使用了210次密钥派生函数迭代(顺便说一句,这还不够。我建议花费12次或更多)10
是salt和密码文本,以修改后的Base-64进行连接和编码。前22个字符解码为salt的16字节值。其余字符是密码文本,用于比较身份验证vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
此示例取自Spring Security的PasswordEncoder接口文档
* @param rawPassword the raw password to encode and match
* @param encodedPassword the encoded password from storage to compare with
* @return true if the raw password, after encoding, matches the encoded password from
* storage
*/
boolean matches(CharSequence rawPassword, String encodedPassword);
这意味着,需要匹配用户下次登录时再次输入的密码,并将其与上次登录/注册期间存储在数据库中的Bcrypt编码密码匹配 为了让事情更清楚 注册/登录方向-> password+salt使用由:cost、salt和密码生成的密钥进行加密。我们将该加密值称为
密文
。然后,我们将salt附加到此值,并使用base64对其进行编码。将成本附加到它,这是从bcrypt
生成的字符串:
$2a$COST$BASE64
最终存储该值
攻击者需要做什么才能找到密码?(其他方向这是一个简单的术语 Bcrypt没有数据库,它存储盐 salt以base64格式添加到哈希中 问题是bcrypt没有数据库时如何验证密码
bcrypt所做的是从密码散列中提取salt…使用提取的salt加密普通密码,并将新散列与旧散列进行比较,看它们是否相同…OK,因此我注册了一个站点并选择了一个密码“foo”。
bcrypt
添加了一个随机的salt“akd2!*”,结果是“fooakd2!*”,它被散列并存储。稍后,我尝试使用密码“bar”登录。要查看我是否正确,它需要散列“barakd2!*”。如果盐是随机生成的,它如何知道如何在散列和比较之前将其添加回“bar”?@Nathan:bcrypt
知道如何从生成的输出中提取盐(存储在数据库中)。在进行身份验证时,bcrypt
将原始输出分为散列和salt组件。salt组件应用于用户键入的传入密码。要回答Nathan Long的评论,一个很好的思路是,salt并不意味着机密。这就是为什么salt包含在输出中的原因正如上面指出的答案之一,salt是用来防止彩虹表的,彩虹表是常用密码的列表,或者只是蛮力,等等不同密码的列表,但是被散列。没有salt,数据库a中密码的散列将与数据库B中密码的散列相同。salt只是在t上更改他散列值