I though I understood hashing and salting passwords but it seems I have some misconceptions. I am creating a user account system for my website in nodejs.
The way I understood it was that when a user creates a password we generate a random salt, append it to the password and then hash that string. We can also add a work factor to make the hash work slowly and defend against brute force attacks. We store the salt along with the hash in our database and to validate a login attempt we repeat the above process (on the server) with the stored salt and the attempted password and check to see if the hashes match.
It seems that the bcrypt
module in nodejs is not consistent with my interpretation of hashing. This is from an example at http://codetheory.in/using-the-node-js-bcrypt-module-to-hash-and-safely-store-passwords/
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync("my password", salt);
First off why is the work factor applied to the salt rather than the hash? If someone is attacking by brute force they would run the hash function correct? Isn't the hash the function we need to be slow?
I'm also confused by validation with bcrypt:
bcrypt.compareSync("my password", hash);
We need the hashes to be unique even if two users select the same password, this is the point of salt right? So why don't we do this?
bcrypt.compareSync("my password"+salt, hash);
SALT
is degree of 2 number (from 4 to 31) - circles of iteration working of function creating hash. bcrypt
take the salt, multiply 2 by itself salt times. And take this value to implement decode function to our string the total amount times. It's "rounder" of loop in bcrypt function.
Every time when you do:
bcrypt.hashSync("my password", salt)
bcrypt
create NEW "random" string, every time use same input string and use the same salt
we take the different output string, it's key idea of working bcrypt function, and this total result we'll save to our base.
Then we use:
bcrypt.compareSync("my password", hash);
And compareSync
calculate if hash was created from string "my password". And if we into function compareSync
add salt to our string ("my password") we'll change the started string and never take true
in this way. Because bcrypt
will compare hash
like if that was created this way:
bcrypt.hashSync("my password"+salt, salt);
That's way we should use this construction:
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync("my password", salt);
hash
to dbnext step authentication user during login like:
bcrypt.compareSync("my password", hash);
without any salt
or parameters.