Search code examples
javascriptnode.jscryptographybcrypt

Why does the hash compare outputs true even without the salt parameter?


I use bcrypt-nodejs to generate a hash in my node.js app like that:

           var complete_string = "login" + "[email protected]";
           var salt = "89Uhfdsua8aHK";
           var hash = bcrypt.hashSync(complete_string, salt);

Then I try to check whether the hash from that string is correct using:

           bcrypt.compareSync(complete_string, hash)); // true

But why does the compareSync function outputs true even though I'm not giving it any salt parameter?


Solution

  • If you inspect hash, you'll notice that hashSync() prepends the salt to the output:

    const bcrypt = require('bcrypt-nodejs');
    const complete_string = "login" + "[email protected]";
    const salt = bcrypt.genSaltSync(2);
    console.log("salt: " + salt);
    const hash = bcrypt.hashSync(complete_string, salt);
    console.log("hash: " + hash);
    console.log("compare: " + bcrypt.compareSync(complete_string, hash));
    

    Outputs:

    salt: $2a$10$k/a9i/zMGnzx5VKjmhXySO
    hash: $2a$10$k/a9i/zMGnzx5VKjmhXySO.sx6fcIPsdbej1pVVcKLy9TbNK.2aLm
    compare: true
    

    It's common to store the salt with the hashed value for exactly this reason, so that it's possible to validate the hash later without having to pass the salt around as a separate value. The bcrypt library just happens to do this for you.