Data Encryption And Decryption In Node.js

As we know, for better security purpose modern web development requires data encryption to encrypt sensitive user data. In this article, we will learn about data Encryption and Decryption in Node.js using Crypto.

What is Encryption?

Encryption is the process of taking plain text and converting it into an unreadable format also known as Ciphertext. This helps protect the confidentiality of digital data either stored on computer systems or transmitted through a network like an internet.

What is Decryption?

Decryption is the process of taking Ciphertext and converting it into a readable format also known as Plaintext.

We use the same key to Encrypt the data and with the same key, we can Decrypt the data. This means a single key is required for data Encryption and Decryption.

 

Let us understand it with an example.

Lets Initialize New Project

npm init

Enter project name (encrypt-decrypt) and other details or you can just skip. After that package.json file is generated automatically. Now create new files as given below.

Project Structure

Install Dependencies

These are the dependencies we have to install in our project for data Encryption and Decryption in Node.js.

npm i crypto express ejs body-parser

Crypto: Required for data encryption and decryption.

Express: Optional, can be used to add Express web application framework.

Ejs: Optional, can be used to add EJS (Embedded JavaScript Templating) template engine.

Body-parser: Optional, can be used to parse incoming request bodies in a middleware.

 

Now let’s create demo application to achieve data Encryption and Decryption in Node.js with Express framework.

Firstly add below code to index.js file. You can modify it as per your need and I have added some comments for better explanation.

const express = require("express");
const path = require('path');
const bodyParser = require('body-parser');

const app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

// for parsing application/json
app.use(bodyParser.json());
// for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

app.use('/', function (req, res) {
    res.render('index');
});

app.listen(5000, () => console.log('Server Running at port 5000'));

Then add below code to crypto.js file. This file contains main code for data Encryption and Decryption. I have created my own separate modules (Encrypt & Decrypt) for this, so I can re-used it in another module when required.

Secret Key length is dependent on algorithm. For aes192 it’s 24 bytes and for aes256 it’s 32 bytes.

Example Secret Key for aes-256-ctr algorithm: 47siGQAkgsuB4y3EZlKate7XGottHski147siGQAkgs=

const crypto = require('crypto');
const algorithm = 'aes-256-ctr';
const secretKey = 'PUT YOUR SECRET KEY HERE';
const encryptionKey = Buffer.from(secretKey, 'base64');

exports.encrypt = function (data) {
    try {
        const iv = crypto.randomBytes(16);
        const cipher = crypto.createCipheriv(algorithm, Buffer.from(encryptionKey, 'hex'), iv);
        const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
        return iv.toString('hex') + ':' + encrypted.toString('hex');
    } catch (err) {
        return undefined;
    }
};

exports.decrypt = function (data) {
    try {
        const textParts = data.split(':');
        const iv = Buffer.from(textParts.shift(), 'hex');
        const encryptedText = Buffer.from(textParts.join(':'), 'hex');
        const decipher = crypto.createDecipheriv(algorithm, Buffer.from(encryptionKey, 'hex'), iv);
        var decrypted = decipher.update(encryptedText);
        decrypted = Buffer.concat([decrypted, decipher.final()]);
        return decrypted.toString();
    } catch (err) {
        return undefined;
    }
};

Now let’s add below code to index.html file to design form and get input from user for data Encryption/Decryption. You can modify it as per your need, I have used  jQuery AJAX method to access API routes.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
    <label for="plainText">Plain Text:</label><br>
    <input id="plainText" name="plainText" value="John"><br>
    <input type="button" value="Encrypt" onclick="encrypt()">
    <h6>
        Output: <span id="encryptResult"></span>
    </h6>

    <label for="encryptedText">Encrypted Text:</label><br>
    <input id="encryptedText" name="encryptedText" value="cac7a58aad4ce99b24831294a12d7e58:3364dfc9"><br>
    <input type="button" value="Decrypt" onclick="decrypt()">
    <h6>
        Output: <span id="decryptResult"></span>
    </h6>

    <script>
        function encrypt() {
            $.ajax({
                url: 'encrypt',
                type: 'POST',
                data: { plainText: $("#plainText").val() },
                success: function (res) {
                    $("#encryptResult").text(res.encryptedText);
                },
                error: function (err) {
                    console.log(err);
                }
            });
        }
        function decrypt() {
            $.ajax({
                url: 'decrypt',
                type: 'POST',
                data: { encryptedText: $("#encryptedText").val() },
                success: function (res) {
                    $("#decryptResult").text(res.decryptedText);
                },
                error: function (err) {
                    console.log(err);
                }
            });
        }
    </script>
</body>

</html>

Then just add routing to index.js file as given below to access Encrypt & Decrypt module from crypto.js file.

const express = require("express");
const path = require('path');
const bodyParser = require('body-parser');
const crypto = require('./crypto');

const app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

// for parsing application/json
app.use(bodyParser.json());
// for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

// for routing
app.post('/encrypt', function (req, res) {
    res.send({ encryptedText: crypto.encrypt(req.body.plainText) });
});
app.post('/decrypt', function (req, res) {
    res.send({ decryptedText: crypto.decrypt(req.body.encryptedText) });
});
app.use('/', function (req, res) {
    res.render('index');
});

app.listen(5000, () => console.log('Server Running at port 5000'));

Output:

Please give your valuable feedback and if you have any questions or issues about this article, please let me know in comment section.

Also, check CRUD Operations In Node.JS Using MongoDB

1 Comment

  1. helpful, Thanks for sharing.

    0
    0
    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories