4

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

  1. 生成盐
  2. 获取密码
  3. 连接盐和密码字符串
  4. 通过您的散列函数对它们进行散列

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

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

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

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> 
4

1 回答 1

4

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

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

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

于 2014-09-18T03:48:25.103 回答