How to hash passwords using bcrypt in Node.js
Bcrypt is a hashing algorithm designed by Niels Provos and David Mazieres based on the
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
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.
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
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));
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 hashbcrypt.hash(password, workFactor, function(err, hash) {console.log(`Hash: ${hash}`);});
On line 7, the bcrypt.hash() function accepts three parameters, as discussed below:
password: The password that is hashed.workFactor: The number of iterations the hashing algorithm performs.function(err, hash): The callback function that returns errorerrif the process fails and returns a hashed passwordhashif 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 hashbcrypt.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:
workFactor: The number of iterations the hashing algorithm performs.function(err, hash): The callback function that returns errorerrif 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:
password: The password that is hashed.salt: The salt generated in thegenSaltfunction.function(err, hash): The callback function that returns errorerrif the process fails and returns a hashed passwordhashif 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 matchedif (result) {console.log("Password verified");}// Password not matchedelse {console.log("Password not verified");}});
On line 6, the compare method accepts three parameters:
password: The password that is hashed.hash: The generated hash of thepassword.function(err, result): The callback function either returns the errorerror theresult. In case the password matches the hash, theresultreturns true. Otherwise, theresultreturns 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
Free Resources