为啥 Ruby 的 bcrypt 库在哈希中包含明文中的盐? [复制]

Posted

技术标签:

【中文标题】为啥 Ruby 的 bcrypt 库在哈希中包含明文中的盐? [复制]【英文标题】:Why does Ruby's bcrypt lib include the salt in plaintext in the hash? [duplicate]为什么 Ruby 的 bcrypt 库在哈希中包含明文中的盐? [复制] 【发布时间】:2014-11-12 04:38:37 【问题描述】:

我正在使用 Coda Hale 的 Ruby bcrypt library。我最近注意到它并没有像我想象的那样工作。我原以为正确的程序是:

    生成盐 获取密码 连接盐和密码字符串 通过散列函数对它们进行散列

但是当我查看 bcrypt 函数的结果时,似乎盐连接到 hash 而不是 password。那就是盐连接发生在步骤#4之后,而不是之前。我假设 Coda Hale 做得对,但我想知道它为什么会这样。

这是一个简短的 IRB 会议,展示了(对我而言)奇怪之处。请注意,在 hash_secret 函数的结果中,前 29 个字符与 salt 相同。任何关于为什么会这样的信息将不胜感激。

我唯一的理论是盐是预先添加的以及嵌入在散列中,这消除了将盐存储在单独的数据库字段中的需要(本质上是一种记录打包策略)? p>

irb#1(main):004:0> password_salt = BCrypt::Engine.generate_salt
=> "$2a$10$OrKdcWORLL8Gorhy9XR3UO"
irb#1(main):005:0> password='abc'
=> "abc"
irb#1(main):006:0> BCrypt::Engine.hash_secret(password, password_salt)
=> "$2a$10$OrKdcWORLL8Gorhy9XR3UOY8Sebzq92m7r02XPitzoazPdO7tmsEO"
irb#1(main):007:0> 

【问题讨论】:

这样盐就不需要与哈希分开存储。盐与密码连接以产生哈希,但盐随后被额外连接到哈希上(连同有关哈希算法的其他元数据),因此只需要单个字符串来测试哈希。 还有How can bcrypt have built-in salts?,这可能是一个更好的资源。 @MichaelBerkowski - 同意 - 我希望在问这个问题之前我已经看到了第二个问题(我确实搜索过!)。我已投票将其标记为重复,因为这回答了我的具体问题.. 【参考方案1】:

这种情况没有技术原因。如果您愿意,您可以分别存储盐和密码。哎呀,如果你愿意,你可以公开盐。我听说有些人会使用用户 ID 作为盐来在他们的数据库中节省一些存储空间。

将哈希值和盐值存储在同一数据库的不同字段中不会带来安全性收益。真正重要的是每种盐都是独一无二的,以阻止彩虹表。

我想创建者决定连接这两个字符串只是为了将盐和散列放在数据库或应用程序的单个字段中。有时这可能很有用,例如在不支持多值返回的语言中。

【讨论】:

这也是在 UNIX 类型系统上保存密码的方式,其中有一个用于存储散列密码的单一字段。该字符串包含有关散列方法、盐和根据相当标准格式的散列的信息。这样,如果您将来更改散列方法,旧的散列密码仍然可以使用。值得注意的是,如果不知道盐和散列方法,就不可能重现散列。

以上是关于为啥 Ruby 的 bcrypt 库在哈希中包含明文中的盐? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Ruby 象征着我的哈希键?

浏览哈希数组以删除Ruby中其他字符串中包含的字符串

为啥在 Ruby 中包含模块的顺序会有所不同?

用 bcrypt (PHP) 比较两个哈希值

错误消息:您已请求:bcrypt-ruby ~> 3.0.1 该捆绑包当前已将 bcrypt-ruby 锁定在 3.0.1。

为啥关键字参数必须作为带有符号键的哈希传递,而不是 Ruby 中的字符串键?