How to encrypt and decrypt a message in Node.js?
Tags: node
Published: 2020-11-30 00:00:00

---
  title: How to encrypt and decrypt a message in Node.js?
  published: true
  tags: Nodejs
  date: Mon Nov 30 2020 05:30:00 GMT+0530 (India Standard Time)
  canonical_url: https://melvingeorge.me/blog/encrypt-decrypt-message-nodejs
  cover_image: https://melvingeorge.me/_next/static/images/main-4875080d3a7b048b6b646a10e0aa88fe.jpg
  ---
  [Originally posted here!](https://melvingeorge.me/blog/encrypt-decrypt-message-nodejs)
  
To encrypt and decrypt a message, we can use the `createCipheriv()` and the `createDecipheriv()` methods respectively in the `crypto` module in Node.js.

To encrypt or decrypt a message we need four things:

- `message` to be encrypted or decrypted
- `algorithm` to use for the encryption and decryption. We will be using the `aes-256-cbc` (aes 256 cipher block chaining) algorithm to encrypt and decrypt the data.
- `key` to encrypt or decrypt the message. This should be an organization or company secret 🤫.
- `iv` or initialization vector, it is a random number generated to increase the security of the encryption and decryption.

### [Jump to the full code &rarr;](#full-code)

## Encrypt a message

First, let's require the `crypto` module.

```js
// get crypto module
const crypto = require("crypto");
```

Now we need to make the iv (initialization vector: Bytes which are generated randomly). For that, the `crypto` module provides a simple function called `randomBytes()` which we can use to generate random bytes of a specified length. Let's pass the number of bytes `16` as an argument to the function like this,

```js
// get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);
```

- The function returns a `Buffer` of random data.

### NOTE: There is an issue with `randomBytes()` function in the `crypto` module [See this](https://github.com/nodejs/node/issues/6696#issuecomment-218575039) to know more. That why we are using the `slice()` method to slice the data to remove some extra data being added by the `randomBytes()` function.

We need to define the message and the secret `key` to be encrypted.

- The `key` should have a length of 32 characters or 32 bytes (since the algorithm uses 256 bits).

```js
// get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";
```

Now let's make the encrypter function using the `createCipheriv()` function from the `crypto` module and pass the algorithm we need to use in our case `aes-256-cbc` as the first argument, the `key` as the second argument, and the `iv` as the third argument.

```js
// get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = crypto.createCipheriv("aes-256-cbc", key, iv);
```

We have made the encrypter function. Now let's encrypt our message using the `update()` method on the `encrypter` and pass the `message` as the first argument, the input encoding (in our case `utf8`) as the second argument, and the output encoding (in our case `hex`) as the third argument like this,

```js
// get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = createCipheriv("aes-256-cbc", key, iv);

// encrypt the message
// set the input encoding
// and the output encoding
let encryptedMsg = encrypter.update(message, "utf8", "hex");
```

Now we need to tell the `encrypter` to stop the encryption once and for all using the `final()` method on the `encrypter` and append data returned by the `final()` method to it. Once the `final()` method is called `encrypter` cannot be used again to encrypt any more data.

The `final()` method returns a `buffer` so we need to set an output encoding of `hex` and append the hex value to the end of the encrypted message like this,

```js
//  get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = crypto.createCipheriv("aes-256-cbc", key, iv);

// encrypt the message
// set the input encoding
// and the output encoding
let encryptedMsg = encrypter.update(message, "utf8", "hex");

// stop the encryption using
// the final method and set
// output encoding to hex
encryptedMsg += encrypter.final("hex");

console.log(encryptedMsg);
```

Yay! We have encrypted our message 🦄. The `encryptedMsg` will be different each time.

### Decrypting a message

Decrypting a message follows the same format and steps followed while encrypting a message.

To decrypt a message we can use the `createDecipheriv()` function from the `crypto` module and pass the algorithm `aes-256-cbc` as the first argument, the `key` used while encrypting the message as the second argument, and the `iv` used while encrypting the message as the third argument.

It can be done like this,

```js
//  get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = crypto.createCipheriv("aes-256-cbc", key, iv);

// encrypt the message
// set the input encoding
// and the output encoding
let encryptedMsg = encrypter.update(message, "utf8", "hex");

// stop the encryption using
// the final method and set
// output encoding to hex
encryptedMsg += encrypter.final("hex");

console.log(encryptedMsg);

// make the decrypter function
const decrypter = crypto.createDecipheriv("aes-256-cbc", key, iv);
```

After that, we can use the `update()` method on the `decrypter` to decrypt the encrypted message by passing the `encryptedMsg` as the first argument.

The second argument is the input encoding of the encrypted message in our case it is `hex` and the third argument is the output encoding after decryption, in our case, it should be `utf8`.

It can be done like this,

```js
//  get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = crypto.createCipheriv("aes-256-cbc", key, iv);

// encrypt the message
// set the input encoding
// and the output encoding
let encryptedMsg = encrypter.update(message, "utf8", "hex");

// stop the encryption using
// the final method and set
// output encoding to hex
encryptedMsg += encrypter.final("hex");

console.log(encryptedMsg);

// make the decrypter function
const decrypter = crypto.createDecipheriv("aes-256-cbc", key, iv);

// decrypt the message
// set the input encoding
// and the output encoding
let decryptedMsg = decrypter.update(encryptedMsg, "hex", "utf8");
```

Now finaly let's use the `final()` method on the `decrypter` to stop the decryption and set the output encoding to `utf8` like this,

<a name="full-code"></a>

```js
//  get crypto module
const crypto = require("crypto");

// generate 16 bytes of random data
const iv = crypto.randomBytes(16).toString("hex").slice(0, 16);

// our secret message
const message = "Hello There, I should be a secret";

// secret key
const key = "12345678123456781234567812345678";

// make the encrypter function
const encrypter = crypto.createCipheriv("aes-256-cbc", key, iv);

// encrypt the message
// set the input encoding
// and the output encoding
let encryptedMsg = encrypter.update(message, "utf-8", "hex");

// stop the encryption using
// the final method and set
// output encoding to hex
encryptedMsg += encrypter.final("hex");

console.log("Encrypted message: " + encryptedMsg);

// make the decrypter function
const decrypter = crypto.createDecipheriv("aes-256-cbc", key, iv);

// decrypt the message
// set the input encoding
// and the output encoding
let decryptedMsg = decrypter.update(encryptedMsg, "hex", "utf8");

// stop the decryption using
// the final method and set
// output encoding to utf8
decryptedMsg += decrypter.final("utf8");

console.log("Decrypted message: " + decryptedMsg);
```

And we have successfully decrypted the encrypted message. 🥳

See code live in [repl.it](https://repl.it/@melvin2016/Encryption-and-decryption-nodejs#index.js).

### Feel free to share if you found this useful 😃.

---