mrg mrg - 2 months ago 15
Ruby Question

BCrypt::Errors::InvalidHash error in Rails

code:

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


Error:

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


Password Encryption Mechanism:

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


The above code product "BCrypt::Errors::InvalidHash" error. My requirement is to get the username and password from client and validate
it with the data stored in db. In database I stored the hashed password for users which is encrypted by bcrypt. So, now I tried to
encrypt the password which is entered by client. After encrypt the current password, it is matched with hashed password stored in db. But it produce the error. How to solve this problem ?

Answer

You need to give BCrypt::Password.new the hash you have stored in the database, not the password the user is submitting. Then you compare that with input received from the user.

Example:

# 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

You can find some more info here: https://github.com/codahale/bcrypt-ruby#how-to-use-bcrypt-ruby-in-general

Also, if you're using Rails >= 3 I'd look into using ActiveModel::SecurePassword with your User model. Some more info here: http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html

Comments