John Geliberte John Geliberte - 5 months ago 21
Ruby Question

Bcrypt ruby on rails

Hi im new to Bcrypt in rails, i was wondering on how to use this gem correctly, as of now i was able to make the password hashed but when comparing it to the user input for the password it does not match.

here is my code for the Encryption and login.

def self.login(user)
hashed_password = encrypt_password(user["password"])
result = User.where({:username => user["username"], :password => hashed_password})
return result
end

def self.add_user(user)
hashed_password = encrypt_password(user["password"])
result = User.create({:username => user["username"],
:password => hashed_password,
:firstname => user["firstname"],
:middle_initial => user["middle_initial"],
:lastname => user["lastname"],
:advisory_class => user["advisory_class"]})
return result
end

def self.encrypt_password(password)
password_salt = BCrypt::Engine.generate_salt
password_hash = BCrypt::Engine.hash_secret(password,password_salt)
end


In the add_user i was encrypting it using the encrypt_password function, when logging in using the login function. the password does not match with the password ecrypted in the databases. im sure im not doing this the right way, can you pin point where am i doing it wrong. thanks.

Answer

The trick here is that BCrypt creates a different result each time you run it with the same password by design. This makes the output of the function extremely unpredictable so it's not practical to brute-force guess passwords.

The way you verify is:

hashed_password = BCrypt::Password.create(user['password'])

The way you verify is:

if @user = User.where(username: user['username'])
  # User found

  if BCrypt::Password.new(@user.password) == user['password']
    # Success!
  else
    # Invalid password
  end
else
  # User not found
end

This works because the == method is overridden for the Password object. It's not doing a literal string comparison.