Ruby BCrypt哈希比较

我正在尝试使用Sinatra和BCrypt实现一个非常简单的身份验证方法,但显然我错过了一些…

用户预先分配了临时密码,该密码以数据库中的明文存储.

我对临时密码进行身份验证,然后创建salt和password_hash,并将其作为字符串写入db(在这种情况下为mongo).

要验证我从db中获取盐和用户密码进行比较.

post "/password_reset" do
  user = User.first(:email => params[:email],:temp_password => params[:temp_password])
  if dealer != nil then
  password_salt = BCrypt::Engine.generate_salt
  password_hash = BCrypt::Engine.hash_secret(params[:password],password_salt)
  user.set(:password_hash => password_hash)
  user.set(:password_salt => password_salt)
  end
end

post "/auth" do
  @user = User.first(:email => params[:email])
  @user_hash = BCrypt::Password.new(@user.password_hash) #because the password_hash is  stored in the db as a string,I cast it as a BCrypt::Password for comparison
  if @user_hash == BCrypt::Engine.hash_secret(params[:password],@user.password_salt.to_s)   then
    auth = true
  else
    auth = false
  end
end

BCrypt :: Engine.hash_secret(params [:password],password_salt)返回的值与db中存储的值不同(都是BCrypt :: Password类,但不匹配).

在这里缺少什么?非常感谢任何见解!

渣子

解决方法

BCrypt :: Password是String的一个子类,它使 overrides the == method使检查密码更容易.当你做的
if @user_hash == BCrypt::Engine.hash_secret(params[:password],@user.password_salt.to_s)

你最后两次执行哈希,所以他们不匹配.如果直接与@ user.password_hash进行比较,而不是使用BCrypt :: Password.new,则应该会看到它们匹配.

使用bcrypt-ruby作为密码的“正确”方式是根本不使用Engine类,只是使用Password类.你不需要自己管理盐,bcrypt会照顾它,并将其包含在密码哈希字符串中:

password_salt = BCrypt::Engine.generate_salt
password_hash = BCrypt::Engine.hash_secret("s3kr1t!",password_salt)

puts password_salt
puts password_hash

产生这样的东西:

$2a$10$4H0VpZjyQO9SoAGdfEB5j.
$2a$10$4H0VpZjyQO9SoAGdfEB5j.oanIOc4zp3jsdTra02SkdmhAVpGK8Z6

如果运行它,会产生稍微不同的东西,因为会生成不同的盐,但是您可以看到密码哈希包含盐.

在你的情况下,你想要这样的东西:

post "/password_reset" do
  user = User.first(:email => params[:email],:temp_password => params[:temp_password])
  if dealer != nil then
    password_hash = BCrypt::Password.create(params[:password])
    user.set(:password_hash => password_hash) # no need to store the salt separately in the database
  end
end

post "/auth" do
  @user = User.first(:email => params[:email])
  @user_hash = BCrypt::Password.new(@user.password_hash)
  if @user_hash == params[:password]  then # overridden == method performs hashing for us
    auth = true
  else
    auth = false
  end
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...