简体   繁体   中英

Rebuild/Verify Ruby on Rails Bcrypt password hash in Javascript

I have to rebuild a project from Ruby on Rails to Node.js. Bcrypt was used to hash passwords in the Ruby project and I'm trying to rebuild the same hash so I can copy the hashed password and users can login with the same credentials on the node version.

This hash $2a$11$j2IA8cPRFFC4YOXTl5kb9eF02fwNdLyFAPOvflQ3h/QdX8mE1SNK2 is used for the password Test1234 . I've checked the Ruby on Rails code and I saw the following function to hash a password

General info

COST = 11
SALT = 1234567890

Create hash

def password_hash(password)
  pwd = "#{password}#{SALT}"
  ::BCrypt::Password.create(pwd, cost: COST)
end

Does passwords match?

def password_match?(password = nil)
  password ||= @params[:password]
  encrypted_password = get_encrypted_password
  return false if !encrypted_password || encrypted_password.size < 8

  pwd = "#{password}#{SALT}"
  BCrypt::Password.new(encrypted_password) == pwd
end

def get_encrypted_password
  return unless @account

  @account.encrypted_password
end

As far as I know something about Ruby this means that in the password_match function, pwd would be Test12341234567890 and BCrypt::Password.new($2a$11$j2IA8cPRFFC4YOXTl5kb9eF02fwNdLyFAPOvflQ3h/QdX8mE1SNK2) checks if Test12341234567890 (pwd) matches the hash.

When I use an online Bcrypt verifier like https://bcrypt.online/ and enter the hash together with the pwd value I don't get a match.

I also tried to use the bcrypt.compare method in the Javascript package but this didn't work either.

What am I missing?

So we did an oopsie and solved this issue in the comments. Here is a recap of it all as an answer.

Me:

I tried your password_hash function with "Test1234" and the salt you provided. Got $2a$11$bhdYASCaEPv/0HXv3OFtIupv8CgHFoEWkMonShKnNN1fkmRIg.07S as a result, ran it through the online verifier you linked and got "The supplied hash matches with supplied plain text".

BCrypt::Password.new(password_hash("Test1234")) == "Test12341234567890" Also works out fine and returns true.

Also tried Node.js with bcryptjs and did bcrypt.compareSync('Test12341234567890', "$2a$11$bhdYASCaEPv/0HXv3OFtIupv8CgHFoEWkMonShKnNN1fkmRIg.07S"). Also works out fine and returns true.

Thore:

Yes that's a new hash you created with the same methods. But for some reason the already created hash $2a$11$j2IA8cPRFFC4YOXTl5kb9eF02fwNdLyFAPOvflQ3h/QdX8mE1SNK2 for password Test1234 that is currently stored in the database doesn't pass the online verification test and the compareSync test in node.js

Me:

That should give you the idea that the problem is not with the Ruby's hash creation function, nor is it with the Node's hash testing function, but somewhere else (which is technically outside the scope of this question). Maybe your database doesn't store the full hash for some reason, or stores it in a wrong way. Maybe something somewhere strips or escapes some characters in the hash, leaving you with incomplete one. Maybe some of the aforementioned happens to the salt. Maybe the hash in the database was generated by a different or older hash function. Maybe the salt has changed.

Thore:

Thanks for the comment! With your comment I found out that they used a different salt than the one inside the .env file. It was stored in the config variables of Heroku. Everything is working now!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM