has_secure_password函数是否使用任何形式的加盐?

70

我希望使用has_secure_password将加密后的密码存储在数据库中。我在互联网上找不到has_secure_password是否使用任何形式的盐值。如果它使用了盐值,那么它是如何工作的呢?有人可以为我澄清一下吗?

Thijs

1个回答

93

has_secure_password 使用 bcrypt-rubybcrypt-ruby 自动处理加盐的存储和生成。从bcrypt-ruby中得到的典型哈希值看起来像这样:$2a$10$4wXszTTd7ass8j5ZLpK/7.ywXXgDh7XPNmzfIWeZC1dMGpFghd92e。该哈希值是使用以下函数进行内部拆分的:

def split_hash(h)
  _, v, c, mash = h.split('$')
  return v, c.to_i, h[0, 29].to_str, mash[-31, 31].to_str
end

这个函数的示例哈希结果如下:

  • 版本:2a
  • 成本:10
  • 盐值:$2a$10$4wXszTTd7ass8j5ZLpK/7.
  • 哈希值:ywXXgDh7XPNmzfIWeZC1dMGpFghd92e

BCrypt::Password == 函数会提取盐并将其应用于传递的字符串:

BCrypt::Password.create('bla') == 'bla' # => true

1
我认为作者是在询问是否需要一个单独的列来存储盐值。我们无法控制这个盐值,因此对于用户来说,它就像一个哈希扩展器--只要破解其中一个列,就可以很快地破解我们的密码。 - jdoe
14
问题是“has_secure_password是否使用任何形式的盐值?”,它确实使用了。我认为大部分情况下整个数据库都被攻破了,所以盐值保存在额外的列中并没有什么区别。但是,您是正确的,如果只有数据库的单个列受到攻击,则使用额外列更安全。 - fabi
1
为了澄清fabi所说的,bcrypt-ruby会自动生成一个盐值,并将其与散列后的密码串联在一起存储在“password_digest”列中。请参阅 https://github.com/codahale/bcrypt-ruby#salts - Ryenski
1
没有回答用户的问题。 用户问我们是否可以自己添加盐?因为当我测试一个示例密码“indu”并检查不同版本的bcrypt生成的哈希以及在不同的机器上时,哈希是相同的。如果加了盐,不同的安装/应用程序将生成不同的哈希,因此如果数据库被黑客攻击,但未提到盐的文件,则黑客将无法根据某些哈希数据库检查密码哈希。 - Indu Pillai
1
我猜你的环境出了点问题,当我在irb中重复运行BCrypt::Password.create('indu')时,每次调用都会得到不同的哈希值(正如预期的那样)。 - fabi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接