Lesson 20 of 50 – Crypto Module
40% Completed
40%

Node.js Crypto Module

The Node.js Crypto module provides cryptographic functionality such as hashing, generating random values, creating HMACs, and working with encryption and decryption.

In simple words: The Crypto module helps us perform security-related operations in Node.js. It is a built-in module, so you do not need to install a separate package to use it.

1. Import the Crypto Module

We can import the built-in module using require('crypto') in CommonJS.

Example: Import Crypto
const crypto = require('crypto');

console.log('Crypto module loaded successfully.');
Output:
Crypto module loaded successfully.

The crypto variable gives us access to functions provided by Node.js for cryptographic operations.

2. What Is Hashing?

Hashing converts input data into a fixed-length output called a hash. For the same input and algorithm, the hash is deterministic. Hashing is designed to be a one-way operation, unlike encryption, which is designed to be reversible with the appropriate key.

Example: Create a SHA-256 Hash
const crypto = require('crypto');

const hash = crypto
    .createHash('sha256')
    .update('Hello World')
    .digest('hex');

console.log(hash);
Output:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

The createHash('sha256') method creates a SHA-256 hash, update() supplies the input, and digest('hex') returns the result as a hexadecimal string.

3. Hash Different Text Values

Changing even one character in the input produces a different hash value in normal cryptographic hash algorithms.

Example: Compare Hashes
const crypto = require('crypto');

function makeHash(text) {
    return crypto
        .createHash('sha256')
        .update(text)
        .digest('hex');
}

console.log('Hash 1:', makeHash('hello'));
console.log('Hash 2:', makeHash('Hello'));

The two hash values will be different because hello and Hello are different inputs.

A fast hash such as SHA-256 should not be used alone to store user passwords. Passwords need a dedicated password hashing algorithm such as scrypt, Argon2id, or bcrypt.

4. Generate Random Bytes

The randomBytes() method generates cryptographically strong random bytes. These can be useful for creating random tokens and other security-related values.

Example: Generate Random Bytes
const crypto = require('crypto');

const randomValue = crypto.randomBytes(8);

console.log(randomValue);
console.log(randomValue.toString('hex'));
Example Output:
<Buffer ...>
a1b2c3d4e5f60708

Your actual output will differ each time. Eight bytes produce 16 hexadecimal characters.

5. Generate a Random Token

A random token can be used as an unpredictable identifier or temporary token. Always protect tokens that grant access to private resources.

Example: Create a Token
const crypto = require('crypto');

const token = crypto.randomBytes(32).toString('hex');

console.log(token);
Example Output:
64 hexadecimal characters representing 32 random bytes

Every run produces a different token. A 32-byte token contains 256 bits of random data.

6. Create an HMAC

HMAC stands for Hash-based Message Authentication Code. It uses a secret key and a hash algorithm to produce a value that can help verify message integrity and authenticity.

Example: Generate an HMAC
const crypto = require('crypto');

const secret = 'my-secret-key';
const message = 'Hello Node.js';

const hmac = crypto
    .createHmac('sha256', secret)
    .update(message)
    .digest('hex');

console.log(hmac);

This prints a hexadecimal HMAC. The output depends on both the message and the secret key. In real applications, keep secret keys out of source code and use environment variables or a secure secret manager.

7. Generate a UUID

A UUID is a universally unique identifier. Node.js provides randomUUID() for generating a random version 4 UUID.

Example: Create a UUID
const crypto = require('crypto');

const id = crypto.randomUUID();

console.log(id);
Example Output:
e.g. 123e4567-e89b-42d3-a456-426614174000

Your UUID will normally be different every time you run the program.

8. Compare Secret Values Safely

Node.js provides timingSafeEqual() to compare equal-length byte sequences in a way designed to avoid timing-based information leaks.

Example: Timing-Safe Comparison
const crypto = require('crypto');

const first = Buffer.from('secret123');
const second = Buffer.from('secret123');

const isEqual =
    first.length === second.length &&
    crypto.timingSafeEqual(first, second);

console.log(isEqual);
Output:
true

The lengths must match before calling timingSafeEqual(), or it throws an error. This method alone does not make an entire application free of timing side channels.

9. Derive a Key Using scrypt()

The scrypt() function is a password-based key derivation function. It is designed to make password guessing more expensive than using a fast hash alone.

Example: Derive a Key
const crypto = require('crypto');

const password = 'example-password';
const salt = crypto.randomBytes(16);

crypto.scrypt(password, salt, 64, (err, derivedKey) => {
    if (err) {
        console.error(err);
        return;
    }

    console.log('Salt:', salt.toString('hex'));
    console.log('Derived key:', derivedKey.toString('hex'));
});

This example generates a random salt and derives a 64-byte key asynchronously.

For real password storage, save the salt and derived password hash together, and use a suitable password hashing configuration. Never store plaintext passwords.

10. Important Crypto Methods

Method Purpose
createHash() Creates a hash object.
randomBytes() Generates cryptographically strong random bytes.
randomUUID() Generates a random version 4 UUID.
createHmac() Creates a keyed hash authentication code.
scrypt() Derives a key from a password and salt.
timingSafeEqual() Compares equal-length byte sequences using a timing-safe operation.
createCipheriv() Creates a cipher using a specified algorithm, key, and IV.
createDecipheriv() Creates a decipher for supported encryption algorithms.

11. Practical Example: Create a Hash Function

We can create a reusable function that generates a SHA-256 hash for any text value.

Complete Program
const crypto = require('crypto');

function generateHash(text) {
    return crypto
        .createHash('sha256')
        .update(text)
        .digest('hex');
}

const firstHash = generateHash('Soopro Pathshala');
const secondHash = generateHash('Node.js');

console.log('First Hash:', firstHash);
console.log('Second Hash:', secondHash);

Both hash values will be different because the input strings are different.

Save this program as hash_example.js and run: node hash_example.js.

📝 Practical Assignment

Practice Tasks
Create a Node.js program that performs these tasks:
  1. Import the built-in crypto module.
  2. Generate a SHA-256 hash for your name.
  3. Generate 16 random bytes and display them as hexadecimal.
  4. Generate a random UUID.
  5. Create an HMAC for a message using a secret key.
  6. Use scrypt() to derive a key from a password and salt.

Challenge: Create a program that generates a random token and verifies whether a supplied token matches the expected value using an appropriate safe comparison.


🧠 Quiz – Crypto Module

Select the correct answer for each question.

1. Which method creates a hash object in Node.js?

2. Which method generates cryptographically strong random bytes?

3. Should SHA-256 alone be used to store user passwords?