Node.js provides a built-in module called crypto that you can use to encrypt and decrypt strings, numbers, buffers, streams, and more. This module offers cryptographic functionality that includes a set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions.

In this article, you'll learn how to use Node.js crypto module to perform cryptographic operations on data. I'll show you how to encrypt data with a secret key and then decrypt it using the same secret key when required.

For the sake of simplicity, I shall use AES (Advanced Encryption System) algorithm CTR encryption mode. Here is a good discussion on StackOverflow for choosing the correct AES encryption mode.

Create a new project

Create a new directory in your local file system and switch to it by typing the following:

$ mkdir crypto && cd crypto

Now execute the following command to initialize a new Node.js project:

$ npm init -y

The above command will create a new package.json file in the root directory. Make sure that you have already installed Node.js on your machine before issuing the above command.

By default, the crypto module is already included in pre-built Node.js binaries. But if you have manually installed Node.js, crypto may not be shipped with it. However, you can install it by executing the following command:

$ npm install crypto --save

Encrypt and decrypt text

Let us create the crypto.js file in the project's root directory and define our encryption and decryption functions as shown below:

crpyto.js

const crypto = require('crypto')

const algorithm = 'aes-256-ctr'
const secretKey = 'vOVH6sdmpNWjRRIqCc7rdxs01lwHzfr3'

const encrypt = text => {
  const iv = crypto.randomBytes(16)

  const cipher = crypto.createCipheriv(algorithm, secretKey, iv)

  const encrypted = Buffer.concat([cipher.update(text), cipher.final()])

  return {
    iv: iv.toString('hex'),
    content: encrypted.toString('hex')
  }
}

const decrypt = hash => {
  const decipher = crypto.createDecipheriv(algorithm, secretKey, Buffer.from(hash.iv, 'hex'))

  const decrpyted = Buffer.concat([decipher.update(Buffer.from(hash.content, 'hex')), decipher.final()])

  return decrpyted.toString()
}

module.exports = {
  encrypt,
  decrypt
}

The following example demonstrates how you can encrypt and decrypt text data (strings, numbers, etc.) by using the above functions:

crpyto-text.js

const { encrypt, decrypt } = require('./crypto')

const hash = encrypt('Hello World!')

console.log(hash)

// {
//     iv: '237f306841bd23a418878792252ff6c8',
//     content: 'e2da5c6073dd978991d8c7cd'
// }

const text = decrypt(hash)

console.log(text) // Hello World!

Encrypt and decrypt buffers

You can also encrypt and decrypt buffers by using the functions defined above. Just pass the buffer in place of the string, and it should work:

crpyto-buffer.js

const { encrypt, decrypt } = require('./crypto')

const hash = encrypt(Buffer.from('Hello World!', 'utf8'))

console.log(hash)

// {
//     iv: '692e44dbbea073fc1a8d1c37ea68dffa',
//     content: 'bbffd902d55d7a00f3a0504e'
// }

const text = decrypt(hash)

console.log(text) // Hello World!

Encrypt and decrypt streams

You can also encrypt and decrypt streams by using the crypto module, as shown in the following example:

crpyto-stream.js

const crypto = require('crypto')
const fs = require('fs')

const algorithm = 'aes-256-ctr'
const secretKey = 'vOVH6sdmpNWjRRIqCc7rdxs01lwHzfr3'
const iv = crypto.randomBytes(16)

// input file
const r = fs.createReadStream('file.txt')

// encrypt content
const encrypt = crypto.createCipheriv(algorithm, secretKey, iv)

// decrypt content
const decrypt = crypto.createDecipheriv(algorithm, secretKey, iv)

// write file
const w = fs.createWriteStream('file.out.txt')

// start pipe
r.pipe(encrypt).pipe(decrypt).pipe(w)

Source Code: Download the complete source code of this project from GitHub, available under the MIT license.

Conclusion

In this article, we looked at how to perform cryptographic operations on text, buffers, and streams using the Node.js built-in crypto module. This is extremely useful if you need to encrypt sensitive data like secret keys before storing them in a database.

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.