Why do I need to store the salt for generated hashes? I am new to crypto and authentication so have been doing reading around this and thought that I had a pretty good understanding of how this works. However when implementing my hashing using bcrypt.js I am once again confused.

I thought that the steps were:

Store Credentials:


Generate random salt
Append salt to password
Generate hash from concatenated string
Store the username, hash and salt


Verify User:


Find user record using username
append stored salt to entered password
hash concatenated string
compare generated hash with stored hash


However reading the bcrypt.js readme I can generate with:

var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync("B4c0/\/", salt);


then compare with:

bcrypt.compareSync("enteredPassword", storedHash)


So it seems that there is no need to store the salt at all.

Also looking at the generated hashes:

[
    {
        "username": "UserOne",
        "hash": "$2a$10$M6qZCSbwhXipdmMy7kQ4V.obtALLSAjZsMYD/oGDAo0i/fcSGrmn2",
        "salt": "$2a$10$M6qZCSbwhXipdmMy7kQ4V."
    },
    {
        "username": "UserTwo",
        "hash": "$2a$10$Yb04C6pVgKVdNjHRB42vKOkr5Wf4QVG8gXyXVqZWnzCs6/MFnIC9G",
        "salt": "$2a$10$Yb04C6pVgKVdNjHRB42vKO"
    }
]


The salt seems to be appended to the hash. Not appended to the password before hashing. This seems pretty pointless to me as any attacker could just strip the salt from the hashes to get a table of not salted hashes.

As I said I am really new to this stuff and getting my head around it is a little difficult. Any simple explanations much appreciated.
The hash returned by bcrypt.hashSync is more than the hash itself, it contains all parameters needed by bcrypt. You do not need to store anything else yourself, this information is everything bcrypt needs to hash and compare an incoming password.

The actual hash was computed by combining the password and salt, so no worries there. The structured data is there merely to make your life easier and only need a single object to store.

In your first example, the output is:

$2a$10$M6qZCSbwhXipdmMy7kQ4V.obtALLSAjZsMYD/oGDAo0i/fcSGrmn2

This breaks down into:


version information: 2a
the number of rounds to perform: 10
the salt: M6qZCSbwhXipdmMy7kQ4V.
the actual hash: obtALLSAjZsMYD/oGDAo0i/fcSGrmn2


You can see the details in the code