how does password hash+salt work

gloo picture gloo · Feb 20, 2014 · Viewed 7.8k times · Source

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);

Answer

Vitaliy Andrusishyn picture Vitaliy Andrusishyn · Jan 25, 2017

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:

  • create hash during create user data: var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync("my password", salt);
  • saving hash to db
  • next step authentication user during login like:

    bcrypt.compareSync("my password", hash);

without any salt or parameters.