DEV Community

Cover image for Password Hashing in Node.js Using bcryptjs Library.
Walkr's-Hub
Walkr's-Hub

Posted on

Password Hashing in Node.js Using bcryptjs Library.

Our Objective

Here's the picture, You are creating your web application that takes in user information, It could be things such as Credit Card Number, National Identification Number, or even Password e.t.c But when you save it, you still get the raw user data being stored exactly the way it has been inputted. How do we go about hashing certain user information so that we can better secure our data?

Data like these are typically stored in a database, and we need a way to encrypt such data so that it doesn't become easily accessible. Even If someone were to hack our database, all they would see is just a bunch of hashed data they can't do anything with.

robot hashing passwords

Our Development Tool

We would be using the bcryptjs library to achieve this goal, It is a very secure and widely used hashing algorithm, which has a lot of cryptographical use cases. This library will help us solve our security problem. You can click here to learn more about the library.

Prerequisites

  • Basic Understand of Arrow Functions.

  • Basic Understanding of Command Line/Terminal.

  • Async - Await.

  • Node is installed

What is Hashing?

Image of hashing

Hashing is the process of transforming any given key or a string of characters into another value. This is usually represented by a shorter, fixed-length value or key that represents and makes it easier to find or employ the original string.

Getting Started

To kick things off, we need a separate file, where we would be storing the logic for our hashing algorithm, this would serve as the playground for understanding how this library works, Before we implement it in our application.

Go ahead and initialize a directory/folder and then create your JavaScript file inside it. My folder name is models and my filename is index.js.

We would start by installing bcrypt into our project folder by using our terminal. We can run the code below to install bcrypt:

npm i bcryptjs
Enter fullscreen mode Exit fullscreen mode

You should have this result printing:

output of installing bcryptjs

Writing our Logic

Before we start hashing our data, we need to require the bcryptjs library into our index.js file, this gives us access to the functions necessary for our goal. You can write the code to save the library into a variable.

const bcrypt = require("bcryptjs")
Enter fullscreen mode Exit fullscreen mode

Next, we need to create an Async function that would help us work with the promises that would be returned from bcryptjs, This is because it is a promise based library. Let's create an async function.

I would call mine, myFunction() and invoke the function afterwards.

const myFunction = async () => {

}

myFunction()
Enter fullscreen mode Exit fullscreen mode

You can learn more about async-await in my article

Hashing Data

Let us go ahead and create the information we are trying to hash, we'll be using user password as an example, I would create a variable for this password. We would assume it to be the plain text password our user provides to us.

To get this done, type the code below:

const myFunction = async () => {
   const password = "John2468$"
}

myFunction()
Enter fullscreen mode Exit fullscreen mode

Below this code, we are going to be creating the hashed version of this password by using bcrypt .hash() method. This method returns a promise containing the hashed version of our password and we would await it's value and store it in a variable called hashedPassword.

The .hash() method takes in two arguments, The first being the data to be hashed, in this case our user password, which we have access to via the password variable. The second being the number of rounds we want to perform.

The number of rounds determines how many times the hashing algorithm is going to be executed, Based on my experience with the library i find that a very good number for this is 8, as it strikes a good balance between security and speed. If we use a lesser number of rounds, the algorithm becomes easy to crack and if we use too many rounds, the algorithm takes a long time to run.

Here's the code to make this happen:

const bcrypt = require("bcryptjs")

const myFunction = async () => {
    const password = "John2468$"
    const hashedPassword = await bcrypt.hash(password, 8)
    console.log(password);
    console.log(hashedPassword);
}

myFunction()
Enter fullscreen mode Exit fullscreen mode

When we go ahead and log the result of password and hashedPassword, we get the result printing below:

happy guy on ship
We see that the hashing algorithm has hashed our data successfully!

Image description

The hashed version is what we would be storing in our database.
This is the hashed version of our data and is exactly what we'll be typically storing in our database where we have password.

Hashing Algorithms Vs Encryption Algorithms

When we use encryption algorithms, we can get the original version of our encrypted data back, This is sort of like a reversible process.

    (encrypted)                    (reversed)
data ---------> 12&#errr!@#$uihh$7 ---------> data
Enter fullscreen mode Exit fullscreen mode

In the case of hashing algorithms, we are dealing with a typical one way algorithm which is irreversible once hashing has occurred.

    (encrypted)                    
data ---------> 12&#errr!@#$uihh$7 
Enter fullscreen mode Exit fullscreen mode

Now, this is by design, and in this article we are dealing with hashing, which begs the question, How do we go about logging in, so we compare the credentials provided by the user with the one stored in our database just to be sure they are exactly matched.

Comparing Data

bcryptjs gives us a way to compare our stored value, with the one the user would provides when using our API, We would be using the bcrypt.compare() method, which takes in two arguments:

  1. The data to be hashed and compared. i.e user input

  2. The hashed value of that data e.g hashedPassword

Although we are typing this out manually, when we are building api's it would be taken from the users and not just typed by us.

We would create a variable called isMatch and we would use the .compare() method on bcrypt and then pass in the required values, i.e user input and the hashed version we have stored.

Now, we can type the code to get this done, See the code below:

const bcrypt = require("bcryptjs")

const myFunction = async () => {
    const password = "John2468$"
    const hashedPassword = await bcrypt.hash(password, 8)
    console.log(password);
    console.log(hashedPassword);

    const isMatch = await bcrypt.compare("John2468$", hashedPassword);
    console.log(isMatch);
}

myFunction()
Enter fullscreen mode Exit fullscreen mode

When we run our file again, we should get the boolean called true printing.

Image description

Behind the scenes bcrypt has run its hashing algorithm on the user password data, and when compared to the hashedPassword, it shows it to be an exact match.

When we change the value provided such as changing "J" in "John" to "j" we would get a different output printing.

const bcrypt = require("bcryptjs")

const myFunction = async () => {
    const password = "John2468$"
    const hashedPassword = await bcrypt.hash(password, 8)
    console.log(password);
    console.log(hashedPassword);

    const isMatch = await bcrypt.compare("john2468$", hashedPassword);
    console.log(isMatch);
}

myFunction()
Enter fullscreen mode Exit fullscreen mode

Image description
Image description

This is typically what we would need when we are building our applications, it could be a system where users are required to login and you want to compare the password they have provided, with the one you have in your database. This is a highly recommended way of storing such data.

Conclusion

So far we have seen how to hash certain user data before storing them in our database, using the .hash() method of the bcryptjs library where we have to provide the user data and the number of rounds.
We also covered how to compare values with each other using the .compare() method as well.

To see the implementation of this in an actual project, I used bcrypt while building my REST-API-WITH-MONGOOSE project to secure user password, here's a link to the github repo

Top comments (1)

Collapse
 
joxxy profile image
Joke

This is so accurate