How to hash passwords using bcrypt in Node.js

Bcrypt is a hashing algorithm designed by Niels Provos and David Mazieres based on the Blowfish cipherBlowfish is a variable-length, symmetric block cipher with blockSize: 64-bits, keySize: 32-bits to 448-bits and number of rounds: 16.. It is commonly used for passwords and takes regular hashing algorithms further by introducing a salt. The salt is a string mixed up with the password before hashing. It is uniquely generated for each password and thus avoids two similar passwords having similar hash.

Bcrypt iteratively hashes the password to make it more secure. The work factor defines the number of iterations the underlying hash function performs when hashing a password. The greater the number of iterations, the slower would be the processing. However, slower processing is more secure as it is resource intensive for hackers to perform brute-forceA brute force attack involves trying all possible combinations of a password, encryption key, or authentication credential until the correct one is found. attacks. Similarly, fewer iterations are quicker to process but are easily compromised. An ideal work factor is a compromise between resources and security.

Moving on, we will discuss using bcrypt in Node to encrypt passwords in Node applications.

Install bcrypt

First of all, we will install bcrypt. Run the following command in the terminal provided to install bcrypt:

npm i bcrypt

To check if bcrypt is properly installed, use the following command.

npm list bcrypt

You can see the output of the command by running it in the terminal provided below.

Terminal 1
Terminal
Loading...

Hash password using bcrypt

To use bcrypt in our application, we must include the module in our script.

const bcrypt = require ('bcrypt');

Next, define the work factor. As discussed above, a higher work factor means slower but strong hashing.

const workFactor = 8;

To demonstrate, we will define a dummy password. You can change this value according to the working of your application.

var password = "Educative@123";

Moving on, we will generate a salt and hash the password. There are two methods for this task.

Promise pattern to generate salt and hash

The first method is based on the promisePromises are a fundamental feature in JavaScript for managing asynchronous code. pattern. The following code snippet shows the complete function.

bcrypt
.genSalt(workFactor)
.then(salt => {
console.log(`Salt: ${salt}`);
return bcrypt.hash(password, salt);
})
.then(hash => {
console.log(`Hash: ${hash}`);
})
.catch(err => console.error(err.message));
Use promise pattern to generate the salt and hash

We'll first generate a salt using the function genSalt which accepts workFactor as an argument to it. Next, we'll pass generated salt and password to the hash function of bcrypt. This function generates a hash stored in hash variable. In case an error is thrown, the catch block will handle it.

Run the code snippet below to see the output of the function.

const bcrypt = require ('bcrypt');
const workFactor = 8;
var password = "Educative@123";
bcrypt
.genSalt(workFactor)
.then(salt => {
console.log(`Salt: ${salt}`);
return bcrypt.hash(password, salt);
})
.then(hash => {
console.log(`Hash: ${hash}`);
})
.catch(err => console.error(err.message));

The code displays the generated salt and hash. Notice that the function generates a new salt on every execution.

Without promise pattern

The second method combines the functions for generating the salt and hashing the password. The code snippet below shows the complete function.

const bcrypt = require ('bcrypt');
const workFactor = 8;
var password = "Educative@123";
// Combined function to generate salt and hash
bcrypt.hash(password, workFactor, function(err, hash) {
console.log(`Hash: ${hash}`);
});

On line 7, the bcrypt.hash() function accepts three parameters, as discussed below:

  1. password: The password that is hashed.

  2. workFactor: The number of iterations the hashing algorithm performs.

  3. function(err, hash): The callback function that returns error err if the process fails and returns a hashed password hash if the process is successful. This function executes after the completion of the function.

There is a similar method to implement the code above.

const bcrypt = require ('bcrypt');
const workFactor = 8;
var password = "Educative@123";
// Seperate function to generate salt and hash
bcrypt.genSalt(workFactor, function(err, salt) {
bcrypt.hash(password, salt, function(err, hash) {
console.log(`Hash: ${hash}`);
});
});

On line 6, the function genSalt accepts two parameters:

  1. workFactor: The number of iterations the hashing algorithm performs.

  2. function(err, hash): The callback function that returns error err if the process fails and returns a salt is generated successfully. This function executes after the completion of the function.

The salt generated in genSalt is directly passed on to function hash which accepts three parameters:

  1. password: The password that is hashed.

  2. salt: The salt generated in the genSalt function.

  3. function(err, hash): The callback function that returns error err if the process fails and returns a hashed password hash if the process is successful.

Both of the methods discussed above perform the same procedure. The difference in output is due to the different salt generated for every password.

So far, we have generated a hash for the password. We need a method to verify if a hash matches a password. In the next section, we will discuss how to match a hash and a password.

Password verification

To verify if a password matches a given hash, we use compare method of bcrypt. The code snippet below implements the complete function.

const bcrypt = require ('bcrypt');
var password2 = "Bcrypt@123";
var hash = "$2b$08$ihbrrTtUeKlPe3inaQ4Nm..Ylc7BZ.p9PNU80hoSPnTkvNK9MkVLO";
bcrypt.compare(password2, hash, function(err, result) {
// Password matched
if (result) {
console.log("Password verified");
}
// Password not matched
else {
console.log("Password not verified");
}
});

On line 6, the compare method accepts three parameters:

  1. password: The password that is hashed.

  2. hash: The generated hash of the password.

  3. function(err, result): The callback function either returns the error err or the result. In case the password matches the hash, the result returns true. Otherwise, the result returns false.

In the code above, we define a variable password2 to store another password for demonstration. Also, we define another variable hash to store the correct generated hash for password2. Next, the function compare accepts the password, hash, and callback function and prints the result to the console. Since the password and hash match, the code should print Password verified.

You can test out the code given above by generating a hash for your own password and verifying it. Enter your password in the input field provided below to generate hash.

bcrypt.hash(password, workFactor, function(err, hash) {
console.log(`Hash: ${hash}`);
});

Enter the input below to be saved in file __ed_input.txt

Summing it up, bcrypt is a simple yet powerful algorithm to hash your passwords. It is a good practice to implement hashing in your applications to avoid rainbow tableAn attack in which attacker used a precomputed table that contains hash for every letter so hash for a password can be easily determined. and brute-force attacks on your confidential data.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved