Encryption in Node JS with Bcrypt

Ronaldo B.August 1, 20224 min read

Getting to know the Bcrypt library

Security is undoubtedly the biggest concern when it comes to data, sensitive information such as access credentials, private and confidential data. In a world that is fully connected and available like today, where systems are online almost 99% of the time, protecting the information and data that flows on the network is the main mission of developers alongside application performance.

Among the many security options available today, the Bcrypt library stands out, created by Niels Provos and David Mazières, cryptographers and researchers who created a cryptographic system that uses password hashing. This algorithm is one of the most secure currently, as it allows adding a random code to the original hash, and also allows increasing the difficulty of deciphering the hash by adding a salt. Allowing the use of computational power to encrypt the data.

By adding codes to the original hash, it prevents brute-force attacks and attacks that attempt to reverse the hash's encryption, using rainbow tables.

Used to protect the password systems of OpenBSD in addition to Linux distributions like SUSE Linux, implemented in major programming languages, it is also available for JavaScript, and in this article, we will see its use with NodeJS. Although this encryption mechanism commonly uses 56 characters or bytes, it can go up to 72 bytes.

This system is the most recommended for storing sensitive data in databases, such as passwords, CPF, RG, or internal company ID, as in case the data is exposed, the attacker will not be able to revert to clear text, even using rainbow tables.

How the BcryptJS library works

With Node.JS it is possible to use the bcrypt library using the third-party module bcrypt. With about 500,000 downloads of the library in the NPM repository, the bcrypt library is among the most popular in the NPM package manager.

For Node.JS version 12.13 we use version 3.0.6 or higher of the bcrypt library.

npm i bcrypt

In the following example, we will apply the bcrypt library to a password hash within a for loop, which will encrypt the password using salts ranging from 10 to 20. When executing the script in Node.JS, note that up to 14, the display is almost instantaneous; depending on the machine you use, it may take a little longer to generate the encryption from 15 to 20.

const bcrypt = require('bcrypt');
const pass = '!]m:#$xDY@p/QDeW';

//examining the hash from 2^10 to 2^20
for (let saltRounds = 10; saltRounds <= 15; saltRounds++) {
  bcrypt.hash(pass, saltRounds)
  .then((passHashed)=> {
    console.time(`Time: ${saltRounds}`);
        console.log(passHashed);
    console.timeEnd(`Time: ${saltRounds}`);
  });
}

This additional time is useful to prevent brute-force attacks; it is recommended that you use up to 240 ms, beyond that it may consume too much computational power. On a Dell Inspiron i7 notebook with 8GB of RAM and Windows 10.

The result was presented below, note that on this machine, salt 12 would be ideal because it is up to 240ms. You can run this script on your server, not necessarily up to 20, giving you an idea of which Salt you should use. Salt has to do with food salt, the seasoning you put in food. You add the right amount of "seasoning" to run your script.

Be aware of the number of milliseconds that encryption generates, up to 240ms is excellent.

Note that in this case, the number of Salt is clearly in the hash; it is in the 5th and 6th position of the hash starting from $. If you do not want to display the Salt number in clear text, it is possible to generate the Salt with the method bcrypt.genSalt, thus the number will not be exposed.

Comparing information

We can use the method bcrypt.compare() to compare the password or data provided with what we already have stored in a database, for example. Thus the compare method will encrypt the provided password and compare it with the encrypted one. It is possible to use async and await to perform this comparison.

In the same file, we will add the compare method below. salt.js

.
.
.
//provided&nbsp;in&nbsp;the&nbsp;form
let&nbsp;userPass&nbsp;=&nbsp;'!]m:#$xDY@p/QDeW'

async&nbsp;function&nbsp;check(username,&nbsp;pass){

 &nbsp;&nbsp; //searching&nbsp;in&nbsp;the&nbsp;database&nbsp;for&nbsp;the&nbsp;user's&nbsp;password
 &nbsp;&nbsp; let&nbsp;passHashedDB&nbsp;=&nbsp;'$2b$12$dbstSfo1FN9jnZOSQ96N7eMMMe9FFI2QmYWo6E44WhutEUg9kZOcW'
 &nbsp;&nbsp;
 &nbsp;&nbsp; const&nbsp;match&nbsp;=&nbsp;await&nbsp;bcrypt.compare(pass,&nbsp;passHashedDB&nbsp;)

 &nbsp;&nbsp; if(match)&nbsp;{
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; console.log('Granted!')
 &nbsp;&nbsp;&nbsp;}else&nbsp;{
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; console.log('Access&nbsp;Denied')
 &nbsp;&nbsp;&nbsp;}
}

//calling the check function
check('JediMaster',userPass)

Note that when running the script again, upon reaching Salt 12, it displays Granted! meaning it is correct. In the example, the variable userPass corresponds to what a user entered in a form in the front-end and was sent via the request. The variable passHashedDB is a query that would be made in a MySQL database, MongoDB, or others, with the encrypted password. We always recommend using the asynchronous version of the methods from the bcrypt library, as this will make the server utilize Node's EventLoop and asynchronous processor threads, increasing application performance.

Comparing the provided password with the encrypted password, after Salt 12: Granted!

So that’s it folks, today we talked a bit about the bcrypt library, if you want to learn more about this and other libs, don’t forget to check our Complete NodeJS Course where we teach the resources of Node in a professional manner, as well as valuable tips like these.

To download the code used in this tutorial, visit: https://github.com/hcodebr/bcrypt-tutorial

See you in the next article!

Glaucio Daniel

Keep learning with Hcode

Sign up for the course platform and follow the next blog guides.