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. This unique value is called a hash. Some examples of hashing algorithms are bcrypt, scrypt, and SHA.

One of the main properties of a good hashing algorithm is that it generates the same output for the same input. This predictability makes hashes vulnerable to brute-force attacks. A hacker can pre-compute hash values for many commonly used inputs and then compare them to the hash values in the target values. You can mitigate this vulnerability using salting.

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 will take them a considerable amount of time 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 the way you hash passwords in Node.js. To use it, follow the steps below:

Step 1: Install Bcrypt

Install bcrypt by running the following terminal commands.

Using npm:

        npm install bcrypt

Using yarn:

        yarn add bcrypt

Step 2: Import Bcrypt

At the top of your JavaScript file, import Bcrypt.

        const bcrypt = require("bcrypt")

Step 3: Generate a Salt

Call the bcrypt.genSalt() method to generate a salt. 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 encrypted password 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

In the bcrypt.genSalt function, pass the plain password and the generated salt to the bcrypt.hash() method to hash the password.

        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 using the bcrypt.compare() function. This function 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 encrypt passwords in Node.js with Bcrypt 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. For example, here is a function that hashes the password using the then...catch block.

        function hashPassword(plaintextPassword) {
    bcrypt.hash(plaintextPassword, 10)
        .then(hash => {
            // Store hash in the database
        })
        .catch(err => {
            console.log(err)
        })
}

Likewise, this function compares a plain password from the user to a hashed password using promises.

        
function comparePassword(plaintextPassword, hash) {
   bcrypt.compare(plaintextPassword, hash)
       .then(result => {
           return result
       })
       .catch(err => {
           console.log(err)
       })
}

Hashing and Salting Is an Easy Win

You can use the Bcrypt library to hash and verify passwords in Node.js. Hashing passwords minimizes the chances of cybercriminals accessing plain passwords and using them to access sensitive data or services.

Salting your hashed passwords makes them even more secure. Apart from hashing, always validate password strength as an added security measure.