How to Hash and Verify a Password in Node.js With bcrypt

One of the best ways to store passwords securely is to salt and hash them. Salting and hashing converts a plain password to a unique value that is difficult to reverse. The bcrypt library lets you hash and salt passwords in Node.js with very little effort.

What Is Password Hashing?

Password hashing means passing a plain text password through a hashing algorithm to generate a unique value. Some examples of hashing algorithms are bcrypt, scrypt, and SHA. The downside of hashing is that it is predictable.

Every time you pass the same input to a hashing algorithm, it will generate the same output. A hacker with access to the hashed password can reverse engineer the encryption to get the original password. They may use techniques such as brute-force attacks or rainbow tables. This is where salting comes in.

What Is Password Salting?

Password salting adds a random string (the salt) to a password before hashing it. This way, the hash generated will always be different each time. Even if a hacker obtains the hashed password, it is impractical for them to discover the original password that generated it.

How to Use bcrypt to Hash and Verify a Password

bcrypt is an npm module that simplifies password salting and hashing.

Step 1: Install bcrypt

Using npm:

npm install bcrypt

Using yarn:

yarn add bcrypt

Step 2: Import bcrypt

const bcrypt = require("bcrypt")

Step 3: Generate a Salt

To generate the salt, call the bcrypt.genSalt() method. This method accepts an integer value which is the cost factor that determines the time taken to hash a password. The higher the cost factor, the more time the algorithm takes and the more difficult it is to reverse the hash using brute force. A good value should be high enough to secure the password but also low enough not to slow down the process. It commonly ranges between 5 and 15. In this tutorial, we will use 10.

bcrypt.genSalt(10, (err, salt) => {
    // use salt to hash password
})

Step 4: Hash the Password

Pass the plain password and the generated salt to the hash() method:

bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(plaintextPassword, salt, function(err, hash) {
        // Store hash in the database
    });
})

Once you’ve generated the hash, store it in the database. You will use it to verify a password and authenticate a user trying to log in.

Instead of generating the salt and hash separately, you can also auto-generate the salt and hash using a single function.

bcrypt.hash(plaintextPassword, 10, function(err, hash) {
    // store hash in the database
});

Step 5: Compare Passwords Using bcrypt

To authenticate users, you will need to compare the password they provide with the one in the database. bcrypt.compare() accepts the plain text password and the hash that you stored, along with a callback function. That callback supplies an object containing any errors that occurred, and the overall result from the comparison. If the password matches the hash, the result is true.

bcrypt.compare(plaintextPassword, hash, function(err, result) {
    if (result) {
       // password is valid
   }
});

Using Async/Await

You can hash and verify passwords using async/await as follows.

async function hashPassword(plaintextPassword) {
    const hash = await bcrypt.hash(plaintextPassword, 10);
    // Store hash in the database
}
 
// compare password
async function comparePassword(plaintextPassword, hash) {
    const result = await bcrypt.compare(plaintextPassword, hash);
    return result;
}

Using Promises

The bcrypt library also supports the use of promises.

function hashPassword(plaintextPassword) {
    bcrypt.hash(plaintextPassword, 10)
        .then(hash => {
            // Store hash in the database
        })
        .catch(err => {
            console.log(err)
        })
}
 
function comparePassword(plaintextPassword, hash) {
    bcyrpt.compare(plaintextPassword, hash)
        .then(result => {
            return result
        })
        .catch(err => {
            console.log(err)
        })
}
Exit mobile version