im working with rails and i noticed that my password_digest is different for 2 users with all other fields other than the password digest different. but i used the same password "abcd" for both..
it ended up generating these 2 different hashes
$2a$10$QyrjMQfjgGIb4ymtdKQXI.WObnWK0/CzR6yfb6tlGJy0CsVWY0GzO
$2a$10$dQSPyeQmZCzVUOXQ3rGtZONX6pwvnKSBRmsLnq1t1CsvdOTAMQlem
i thought the bcrypt gem generates the hash only based on the password field! am i wrong? thanks :)
When hashing passwords, two passwords can produce the same hash, so if a user inputs someone else's username but his own password, there is a possibility that he will be able to login to that other account.
This is Expert Verified Answer The answer is salted password hashing. The salted password hashing technique creates different hashes for the same password.
The hash should be different for every single execution. That's the point of a salt (so the same password hashes differently for each user)...
Salted hashesThe salt is just some random data but it ensures that the hash of your password will always be unique, even if others are using the same password. So if Bob and Alice both use the password “qwerty” their hashes will be completely different.
What you are looking at here is more than a password hash, there is a lot of metadata about the hash included in those strings. In terms of bcrypt the entire string would be considered the bcrypt hash. Here is what it includes:
$ is the delimiter in bcrypt.
The $2a$ is the bcrypt algorithm that was used.
The $10$ is the cost factor that was used. This is why bcrypt is very popular for storing hashes. Every hash has a complexity/cost associated with it, which you can think of as how quickly it will take a computer to generate this hash. This number is of course relative to the speed of computers, so as computers get faster and faster over the years it will take less and less time to generate a hash with the cost of 10. So next year you increase your cost to 11, then to 12... 13... and so on. This allows your future hashes to remain strong while keeping your older hashes still in valid. Just note that you cannot change the cost of a hash without rehashing the original string.
The $QyrjMQf... is a combination of the salt and the hash. This is a base64 encoded string.
The first 22 characters are the salt.
The remaining characters are the hash when used with the 2a algorithm, cost of 10, and the given salt. The reason for the salt is so an attacker cannot pre compute bcrypt hashes in order to avoid paying the cost of generating them.
In fact this is the answer to your original question: The reason the hashes are different is because if they were the same you would know that anytime you saw the bcrypt string $2a$10$QyrjMQfjgGIb4ymtdKQXI.WObnWK0/CzR6yfb6tlGJy0CsVWY0GzO
you would know the password would be abcd
. So you could just scan an databases of hashes and quickly find all of the users with the abcd password by looking up that hash.
You cannot do this with bcrypt because $2a$10$dQSPyeQmZCzVUOXQ3rGtZONX6pwvnKSBRmsLnq1t1CsvdOTAMQlem
is also abcd
. And there are many many many more hashes that will be the result of bcrypt('abcd')
. This makes scaning a database for abcd passwords next to impossible.
bcrypt
stores the salt in the password hash.
Those are two different hashes of the same password with two different salts.
When verifying the passwords, bcrypt will read the salt from the hash field, then re-compute the hash using that salt.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With