为什么Ruby的bcrypt lib在哈希中包含纯文本的盐?

Why does Ruby's bcrypt lib include the salt in plaintext in the hash?

本问题已经有最佳答案,请猛点这里访问。

我正在使用Coda Hale的Ruby Bcrypt库。我最近注意到它不像我想象的那样工作。我认为正确的程序是:

  • 生成盐
  • 获取密码
  • 连接salt和密码字符串
  • 通过散列函数散列它们
  • 但当我查看bcrypt函数的结果时,似乎salt连接到了散列,而不是密码。这就是盐串联发生在步骤4之后,而不是之前。我假设科达黑尔这样做是对的,但我想知道为什么会这样。

    这里有一个简短的IRB会议来展示(对我)什么是奇怪的。注意,在hash_secret函数的结果中,前29个字符与盐相同。关于这件事的原因的任何信息将不胜感激。

    我唯一的理论是,盐是预先准备好的,并且嵌入到散列中,这样就不需要将盐存储在单独的数据库字段中(本质上是记录打包策略)?

    1
    2
    3
    4
    5
    6
    7
    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>


    这种情况没有技术上的原因。如果您愿意,可以单独存储salt和密码。见鬼,如果你愿意的话,你可以把盐公之于众。我听说有些人会使用用户ID作为salt,在他们的数据库中保存一些存储空间。

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

    我设想创建者决定将这两个字符串串联起来,以便在数据库或应用程序的单个字段中保持salt和hash在一起。有时这是有用的,例如在不支持多值返回的语言中。