11

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:

  1. Generate random salt
  2. Append salt to password
  3. Generate hash from concatenated string
  4. Store the username, hash and salt

Verify User:

  1. Find user record using username
  2. append stored salt to entered password
  3. hash concatenated string
  4. 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.

Roaders
  • 213
  • 2
  • 5

1 Answers1

45

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

Marc
  • 1,583
  • 1
  • 17
  • 17