/Study-Node-Authentication-and-Encryption-with-Bcrypt

A handy study that explores the functionality of Bcrypt, cryptographic hash functions, and the implementation of salt and hashing which obscure sensitive information.

Primary LanguageJavaScript

Node Authentication and Encryption with Bcrypt Study


What is the Node Authentication and Encryption with Bcrypt Study?

The Node Authentication and Encryption with Bcrypt Study is an examination of security and data confidentiality using the bcrypt encryption library. In this study, a basic express application demonstrates how to post a user name and password to a locally stored user database, login with a user name and password, and show how bcrypt helps add a high level of security to the authentication process.


Study Contents:


What is Authentication?

First, it should be clear that passwords should never be stored as plain text in a database (or anywhere else for that matter) because identifying users and providing corresponding access to thier respective content (depending on their id) keep those passwords safe. For authentication, when a user logs into your system it needs to be checked if it is correct. For example, suppose you have a commerce website that requires users to register and sign into an an account to purchase items. The application would provide a registration and login form with credentials such as a name and password to verify that the user is who they say they are.


What is bcrypt

Bcrypt is a cryptographic hash function which takes a piece of information and returns a string representing this information. The bcrypt library helps add additional security to information the user submits by obscuring sensitive information with hashing and salting. Passwords are passed to bcrypt to calcualte a hash and store that password in a database associated with the user (i.e. hash). Additionally, the bcrypt algorithm uses a random segement called a salt to generate the hash associated with the password. This is all stored with the password and when required, will be compared to the one the user registered with.

    {
        name: Joe Smith
        password: Abc123
    }

When you salt and hash the password, you will end up with a hashed password and salt:

    {
        name: Joe Smith
        password: $2b$10$v.djtI71AcqSPn75sZHTOOyyviecbsQG9ZxcVcIwc9xsfxYvJGhle
    }

How do you implement bcrypt in your authentication?

In this example, we want to secure the password of any user that sends in a POST to our database by hashing and salting the password to store in our database.

STEP 1: Add the "bcrypt" dependency and require it:

    const bcrypt = require('bcrypt');

STEP 2: Add "async" to your POST request

Because bcrypt is an asynchronous library, you need to make the POST request an async/await function. The example below will send the user and password information to the storage variable in our server file unencrypted. We'll change this in a moment but this is what we start with.

    app.post('/users', async function(req, res) {                                // add async modifier
        const user = { name: req.body.name, password: req.body.password}         // store inputs as "user"
        users.push(user);                                                        // and push the user to "users"
        res.status(201).send();                                                  // and send!
    });

STEP 3: Create a try/catch block

Try/catch will try the code and execute if successful, but if not, the catch will send a 500 error code back.

    app.post('/users', async function(req, res) {
        try {                                                                                // try
            const user = { name: req.body.name, password: req.body.password}
            users.push(user);
            res.status(201).send();
        } catch(error) {                                                                     // catch
            res.status(500).send();
        }
    });

STEP 4: At the top of your try block, create a "salt"

To create a salt, you call bcrypt and use the method "genSalt" with any number you want( the larger the number, the longer it will take to generate the hash but the more secure it will be). It is best just to leave this empty. If you use a 10, it could do a few hashes, but 20 or 30 will take DAYS to generate so just dont do it. And make sure make this an "await" since it is an asynchronous function.

    app.post('/users', async function(req, res) {
        try {
            const salt = await bcrypt.genSalt();                                          // salt added

            const user = { name: req.body.name, password: req.body.password}
            users.push(user);
            res.status(201).send();
        } catch(error) {
            res.status(500).send();
        }
    });

And if you log salt, you will see generate a unique string, like the following:

    You app is listening on port 3000... 
    $2b$10$/tJcQTlBJAOoFnDKad3M6O                    <== salt

STEP 5: Next, create a "hashed" password

Remember that when you create the hashedPassword, you need to pass that to the user variable.

    app.post('/users', async function(req, res) {
        try {
            const salt = await bcrypt.genSalt();
            const hashedPassword = await bcrypt.hash(req.body.password, salt);       // hashed password

            const user = { name: req.body.name, password: hashedPassword}            // and pass to user.
            users.push(user);
            res.status(201).send();
        } catch(error) {
            res.status(500).send();
        }
    });

And if you log hashedPassword, you will see the salt and the hashed password.

    You app is listening on port 3000... 
    $2b$10$/tJcQTlBJAOoFnDKad3M6O                                         <== salt
    $2b$10$/tJcQTlBJAOoFnDKad3M6OQKkcOvoQPLo/iYEJLk.gaEvwhFXe39C          <== salt + hashed password

Screenshots

authentication1