【问题标题】:BCrypt::Errors::InvalidHash error in RailsRails 中的 BCrypt::Errors::InvalidHash 错误
【发布时间】:2017-01-24 08:13:15
【问题描述】:

代码:

class LoginController < ApplicationController
  def auth
        if params[:name].present? && params[:pass].present? && params[:role].present?
                @name=params[:name]
                pass=params[:pass]
                role=params[:role]

                epass = BCrypt::Password.new(pass)
        else
                render "argerror"
        end
  end
end

错误:

BCrypt::Errors::InvalidHash (invalid hash):
app/controllers/login_controller.rb:12:in `new'
app/controllers/login_controller.rb:12:in `auth'

密码加密机制:

salt = BCrypt::Engine.generate_salt
pass = BCrypt::Engine.hash_secret(pass, salt)

以上代码产物“BCrypt::Errors::InvalidHash”错误。我的要求是从客户端获取用户名和密码并验证 它与存储在数据库中的数据。在数据库中,我存储了由 bcrypt 加密的用户的哈希密码。所以,现在我试着 加密客户端输入的密码。加密当前密码后,与存储在 db 中的哈希密码匹配。但它会产生错误。如何解决这个问题呢 ?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 model-view-controller bcrypt


    【解决方案1】:

    你需要给BCrypt::Password.new你存储在数据库中的哈希值,而不是用户提交的密码。然后将其与从用户收到的输入进行比较。

    例子:

    # Create hash of password
    pass =  BCrypt::Password.create('TestPassword')
    => "$2a$10$3.D6D2htbiRrezmZUhePV.gaQlc3ZjFYD9hv43khN5eWP5y8BGUXG"
    
    # Pass the hash you have stored to Password.new
    db_hash = BCrypt::Password.new("$2a$10$3.D6D2htbiRrezmZUhePV.gaQlc3ZjFYD9hv43khN5eWP5y8BGUXG")
    
    # Compare the input from the user to the password stored
    db_hash == "TestPassword"
    => true
    
    db_hash == "NotRealPassword"
    => false
    

    您可以在此处找到更多信息:https://github.com/codahale/bcrypt-ruby#how-to-use-bcrypt-ruby-in-general

    另外,如果您使用的是 Rails >= 3,我会考虑在您的 User 模型中使用 ActiveModel::SecurePassword。更多信息在这里:http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html

    【讨论】:

    • 你能解释一下它是如何验证密码的。因为,db 有散列密码,而我们有纯密码。我们只是将散列密码传递给“BCrypt::Password.new(user.password)”。我期望的是我们需要获取提交密码的哈希值并使用该哈希值,我们可以检查存储在 db 中的密码来验证用户登录凭据。但这里有些不同。
    • 当然。 BCrypt::Password.new(user.password) 有一个 == 的公共方法,所以当你调用 db_hash == "plain_text" 时,它在后台所做的是加密你传递的纯文本,然后比较哈希是否相同。您可以在此处的BCrypt 中查看== 的来源:bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009 我希望可以解释 - 如果没有,请告诉我。
    • 因此,这里的“==”与我们在字符串比较中使用的运算符不同。对吗?
    • 差不多了。对不起,如果我的解释很糟糕。 BCrypt 所做的是覆盖 == 运算符并向其添加一些功能。当您在BCrypt::Password.new 上调用== 时,它会在BCrypt::Engine.hash_secret(secret, @salt) 的结果上调用ruby 默认==
    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 2012-06-17
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多