All articles
nodejs

NodeJS - Securing Through Cryptography

Share this article

Share on LinkedIn Share on X (formerly Twitter)

The crypto module

Node.js comes with its own cryptography module out of the box. And this article tries to explain how to get most out of it.

While using internet, your data needs to be traveled multiple places it the world. Cryptography is needed to make sure that your data is not compromised. NodeJS Crypto module provides several classes and methods to encrypt and protect data.

Following is the simple introduction to the classes provided by NodeJS crypto module

  • Cipher/Decipher: Used to encrypt and decrypt data
  • DiffieHellman/ECDH: DiffieHellman is a method of exchanging keys using asymmetric cryptography. ECDH stands for Elliptic-Curve Diffie-Hellman.
  • Hash: Hashes transform plain text data into fixed length random data. Given the output you cannot trace back to the input.
  • HMAC: Hash-based Message Authentication Codes. Sent along with the messages to verify the identity of the sender and the integrity of the message
  • Sign/Verify: Used to cryptographic signing. Verifies the integrity of the document and the identity of the sender

There are other utility methods in crypto module - for generating random numbers, etc.,

Hashing

MD5 stands for Message Digest 5 is not secure enough.

const crypto = require('crypto');
 
// pass the algo you wanted to use
const hash = crypto.createHash('md5');
 
hash.update('password123');
 
const hashedPassword = hash.digest('hex');
 
console.log(hashedPassword); // '482c811da5d5b4bc6d497ffa98491e38'
  • You cannot call digest twice
  • You cannot call update after digest
  • Hashing is not enough to make your data secure. Use salt also. (https://hashtoolkit.com)
  • MD5 is not a strong hashing algorithm (high chance of hash collisions)

Here are the list of recommended algorithms in the order of preference

  1. Argon2 - New but academically proven - introduced in 2013
  2. PBKDF2 - Password-Based Key Derivation Function 2. Useful if you require wide enterprise support in compliance with federal standards such as the Federal Information Processing Standard.
  3. Scrypt - Like PBKDF2, but optimized to resist hardware-based attacks
  4. Bcrypt - Based on Blowfish algorithm.

Read more Using Argon2 with Node

Salt

You need to salt the hash to be more secure. If two users use same password with the same algorithm, with the help of salt the hashes of those two users will be different

  • Use different salts for different users
  • You must create a new salt with every login credential instead of using the same salt for the same user account
const crypto = require('crypto');
 
const password = 'password123';
 
const salt = crypto.randomBytes(256).toString('hex');
 
const hashedPwd = crypto.pbkdf2Sync(password, salt, 100000, 512, 'sha512');
 
console.log(hashedPwd.toString('hex'));

Symmetric Encryption

In symmetric encryption, one key is used to encrypt and decrypt the data.

  • createCipheriv - Creates symmetric ciphers (iv - initialization vector)
  • update - to add data
  • final - to encrypt data

CBC means "Cipher Block Chaining"

const crypto = require('crypto');
 
const algorithm = 'aes-256-cbc';
const password = 'Good strong password for key';
let ssn = '111-000-0000';
 
const salt = crypto.randomBytes(32);
 
// 32 bytes = 256 bits
const key = crypto.scryptSync(password, salt, 32);
 
const iv = crypto.randomBytes(16);
 
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(ssn, 'utf8', 'hex');
encrypted += cipher.final('hex');
 
console.log(encrypted);
 
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted = decipher.final('utf8');
 
console.log(decrypted);

Comments