DEV Community

Cover image for Cipher, Decipher, and Hash using the crypto module in Node.js
Mihir Shah
Mihir Shah

Posted on

Cipher, Decipher, and Hash using the crypto module in Node.js

Whenever we create a server-to-client or client-to-server communication, we should always be curious about how to keep it secure and private. No one wants to compromise the data with any cybercriminal.

So, the question is, how do we protect confidential information?

In this article, I'll introduce one of the most commonly used modules for securing data in Node.js, Crypto.

To implement Crypto in a Node.js application, you should have:

  • Node.js and NPM should be installed in your working environment.

What is a crypto module in Node.js?

The crypto module provides cryptographic functionality that includes a set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign, and verify functions.

How to use crypto classes in Node.js

Node provides a crypto module by default. There is no need to configure or install it manually.

// Import crypto module into your application
const crypto = require("crypto");
Enter fullscreen mode Exit fullscreen mode

Let's cover some of the crypto classes which is used widely nowadays.

Hash:

The hash class is a utility for creating hash digests of data.

Example: Using the createHash(), createHmac(), update(), and digest() methods:

// Import crypto module into your application
const crypto = require("crypto");

// Creating hash without key using cryto
const hash = crypto
  .createHash("sha256")
  .update("some data to hash")
  .digest("hex");

console.log(hash);
Enter fullscreen mode Exit fullscreen mode
// Import crypto module into your application
const crypto = require("crypto");

// Hash data with key
const hmac = crypto
  .createHmac("sha256", "a secret")
  .update("some data to hash")
  .digest("hex");

console.log(hmac);
Enter fullscreen mode Exit fullscreen mode

createHash(algorithm)

In this function, the algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are 'sha256', 'sha512', etc.

createHmac(algorithm, key)

Creates and returns an hmac object that uses the given algorithm and key. For this function, an algorithm is the same as the createHash function.

update(data)

Updates the hash content with the given data.

digest(type)

Calculates the digest of all the data passed to be hashed (using the update() method). If encoding is provided a string will be returned; otherwise, a Buffer is returned.

Widely used digestion formats are 'base64', 'hex', and 'binary'.

Cipher and Decipher:

Instances of the Cipher class are used to encrypt data.

Instances of the Decipher class are used to decrypt data.

The createCipheriv() method is used to create Cipher instances. And the createDecipheriv() method is used to create Decipher instances.

// Node.js example to implement the Cipher and Decipher crypto classes

// Import crypto module into your application
const crypto = require("crypto");
// Algorithm to be used for encryption and decryption
const algorithm = "aes-256-cbc";
// Key to encrypt/decrypt algorithm
const key = crypto.randomBytes(32);
// IV value for algorithm
const iv = crypto.randomBytes(16);

// A cipher/encryption function to encrypt data
function encrypt(text, iv) {
  // Creating Cipheriv method with its parameter
  let cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
  // Calling update method after creating cipher
  let encrypted = cipher.update(text, "utf8", "base64");
  // Calling final method after updating cipher
  encrypted += cipher.final("base64");
  // Returning iv and encrypted data
  return {
    iv: iv.toString("hex"),
    encryptedData: encrypted,
  };
}

// A Decipher/decryption function to decrypt encrypted-data
function decrypt(text) {
  let iv = Buffer.from(text.iv, "hex");
  let encryptedText = Buffer.from(text.encryptedData, "base64");
  // Creating Decipheriv method with its parameter
  let decipher = crypto.createDecipheriv(
    algorithm,
    Buffer.from(key, "base64"),
    iv
  );
  // Calling update method after creating decipher
  let decrypted = decipher.update(encryptedText);
  // Calling final method after updating decipher
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  // returns data after decryption
  return decrypted.toString();
}

// Encryption output
var output = encrypt("some text to encrypt", iv);
console.log(output);

// Decryption output
console.log(decrypt(output));
Enter fullscreen mode Exit fullscreen mode

createCipheriv(algorithm, key, iv, options) / createDecipheriv(algorithm, key, iv, options)

createCipheriv() method is used to create a Cipher object, with the stated algorithm, key, and initialization vector (iv).

createDecipheriv() method is used to create a Decipher object, with the stated algorithm, key and initialization vector i.e, (iv).

  • algorithm: It is a string-type value that is dependent on OpenSSL. The examples are aes128, aes192, etc.

  • key: Key is used by the algorithm and iv. The key must be based on algorithm bits. e.g., if an algorithm is 192 bits key should be a length of 24 bytes. Similarly, if an algorithm is 128 and 256 bits then its key length should be 16 and 32 bytes.

  • iv: It is an initialization vector that must be uncertain and very unique. If the cipher doesn't require iv then it can be null.

  • options: It is an optional parameter that is used to control stream behavior.

update(data[, inputEncoding][, outputEncoding])

This method is used to update the cipher with data according to the given encoding format.

  • data: It is used to update the cipher with new content.

  • inputEncoding: Input encoding format. If the inputEncoding argument is given, the data argument is a string using the specified encoding. If the inputEncoding argument is not given, data must be a Buffer, TypedArray, or DataView. If data is a Buffer, TypedArray, or DataView then inputEncoding is ignored.

  • outputEncoding: Output encoding format. The outputEncoding specifies the output format of the enciphered data. If the outputEncoding is specified, a string using the specified encoding is returned. If no outputEncoding is provided, a Buffer is returned.

final([outputEncoding])

Once the final() method has been called, the Cipher object can no longer be used to encrypt data.

  • outputEncoding: The encoding of the return value.

That's all for this article. For an in-depth look at the cryptographic module, check out the official documentation.

I hope you enjoyed this article. If you did, please clap, follow, and subscribe.

See you at the next one.

Top comments (0)