Confused with bcrypt and Authlogic

I'm in the progress of migrating my website from using Authlogic to my own authentication solution for one reason or another and I've hit a little problem - I've set Authlogic to use bcrypt-ruby for passwords, and now I'm confused as to how I'm supposed to work with the library and authenticate existing users in my database.

For example, I registered a new user on my website with the password "test". Here's the hash and salt stored in the database:

ruby-1.9.2-p0 > u.crypted_password => "$2a$10$71.OHo9IrbKve9Mu7m.FNO6QRedkmGuue3/y/StdhlksBnvlL6GBS" ruby-1.9.2-p0 > u.password_salt => "Hki1ozSQrkmvGzddNJq"

One would assume that I would do something like this to check the password using the bcrypt library:

ruby-1.9.2-p0 > BCrypt::Password.new("$2a $10$71.OHo9IrbKve9Mu7m.FNO6QRedkmGuue3/y/StdhlksBnvlL6GBS") == "hello"

...but the result is "false". Do we need to work the salt in? And if yes, how? Trying to pass it as a constructor argument or trying the "salt" setter doesn't work.

CV wrote:

...but the result is "false". Do we need to work the salt in? And if yes, how? Trying to pass it as a constructor argument or trying the "salt" setter doesn't work.

You're saving the crypted_password and the salt that was used to create it, so the validation of a newly submitted password is to pass it through the same function and compare the end results...

Does Bcrypt of "newly submitted password" and u.password_salt == u.crypted_password

Should you be using something like:

if BCrypt::Engine.hash_secret(password, u.salt) == u.crypted_password   valid = true end

Well, I didn't realize that there was a lower-level part to the library too! But unfortunately we're not there yet:

ruby-1.9.2-p0 > BCrypt::Engine.hash_secret("test", "Hki1ozSQrkmvGzddNJq") BCrypt::Errors::InvalidSalt: invalid salt

CV wrote:

Well, I didn't realize that there was a lower-level part to the library too! But unfortunately we're not there yet:

ruby-1.9.2-p0 > BCrypt::Engine.hash_secret("test", "Hki1ozSQrkmvGzddNJq") BCrypt::Errors::InvalidSalt: invalid salt

I wonder if Authlogic overrode any of the default settings for BCrypt?

What do you get using irb for @version, @cost, @salt, @hash after:

@version, @cost, @salt, @hash = BCrypt::Password.new(u.crypted_password)

on your test user? Source docs indicate Password.new returns a quadruple:

     # File lib/bcrypt.rb, line 161 161: def initialize(raw_hash) 162: if valid_hash?(raw_hash) 163: self.replace(raw_hash) 164: @version, @cost, @salt, @hash = split_hash(self) 165: else 166: raise Errors::InvalidHash.new("invalid hash") 167: end 168: end