DEV Community

Cover image for Encryption in NodeJS with Bcrypt
Pedro Aravena for Vaultree

Posted on • Updated on

 

Encryption in NodeJS with Bcrypt

Getting to know the Bcrypt lib

Security is the biggest concern when it comes to data, sensitive information such as access credentials, private and confidential data. In a fully connected world, where systems are online almost 99% of the time, protecting the information and data that travels through the network is the main mission of developers combined with 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 an encryption system that uses a hash of passwords. This algorithm is one of the safest nowadays, because it allows you to add a random code to the original hash, it also allows you to increase the difficulty of deciphering the hash by adding a salt. Allowing to use computing power to encrypt data.

By adding codes to the original hash, it prevents brute force attacks, and attacks that try to reverse the encryption of the hash, using rainbow tables.

Used to protect OpenBSD password systems in addition to linux distributions like SUSE Linux, implemented in the main 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 be up to 72 bytes.

This system is the most recommended for storing sensitive data in a database, such as passwords, personal ID, or internal company ID, since if the data is exposed, the attacker will not be able to revert to the data in clear text, even using rainbow tables.

How the BcryptJS lib works

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

For Node.JS version 12.13 we use bcrypt lib version 3.0.6 or higher.

npm i bcrypt

In the following example we will apply the bcrypt library to a password hash inside a for loop, which will encrypt the password using salt ranging from 10 to 20. when executing the script in Node.JS, notice that up to 14 the display is almost instantaneous, depending on the machine you use, it may take 15 to 20 minutes to generate the encryption.

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

//examining the hash from 2^10 until 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 above that, it can consume a lot of computational power.

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

Image description

Notice 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 counting from the $. If you don't want to display the Salt number in clear text, you can generate the Salt with the bcrypt.genSalt method, so the number won't be open.

Comparing the information

We can use the bcrypt.compare() method to compare the password or data informed with what we already have stored in a database, for example. So the compare method will encrypt the entered password and compare with the encrypted password. You can use async and await to perform this comparison.

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

let userPass = '!]m:#$xDY@p/QDeW'
async function check(username, pass){

/* searching in the database the user's password */
let passHashedDB = '$2b$12$dbstSfo1FN9jnZOSQ96N7eMMMe9FFI2QmYWo6E44WhutEUg9kZOcW'
const match = await bcrypt.compare(pass, passHashedDB )
if(match) {
console.log('Granted!')
}else {
console.log('Access Denied')
}}

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

Notice that when you run the script again, when you get to Salt 12 it displays Granted! ie is correct. In the example, the userPass variable corresponds to what a user entered in a form on the front-end and was sent through the request. The passHashedDB variable is a query that would be made in a MySQL, MongoDB or other database, with the password encrypted. We always recommend using the asynchronous version of the bcrypt lib methods, this will make the server use the Node EventLoop and asynchronous processor threads, increasing application performance.

Image description

If you want to try it out, download this sample project and run on your machine, click here and download the code sample

-

At Vaultree we are building an encrypted future. We love sharing valuable information and trends to help you keep your data safe. Sign up to stay in the loop and discuss the hottest trends in cybersec with a team of experts.

Image description

Top comments (0)

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.