The Node.js Crypto module provides cryptographic functionality such as hashing, generating random values, creating HMACs, and working with encryption and decryption.
We can import the built-in module using
require('crypto') in CommonJS.
const crypto = require('crypto');
console.log('Crypto module loaded successfully.');
Crypto module loaded successfully.
The crypto variable gives us access to
functions provided by Node.js for cryptographic operations.
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.
const crypto = require('crypto');
const hash = crypto
.createHash('sha256')
.update('Hello World')
.digest('hex');
console.log(hash);
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
The createHash('sha256') method creates a
SHA-256 hash, update() supplies the input,
and digest('hex') returns the result as
a hexadecimal string.
Changing even one character in the input produces a different hash value in normal cryptographic hash algorithms.
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.
The randomBytes() method generates cryptographically
strong random bytes. These can be useful for creating random
tokens and other security-related values.
const crypto = require('crypto');
const randomValue = crypto.randomBytes(8);
console.log(randomValue);
console.log(randomValue.toString('hex'));
<Buffer ...>
a1b2c3d4e5f60708
Your actual output will differ each time. Eight bytes produce 16 hexadecimal characters.
A random token can be used as an unpredictable identifier or temporary token. Always protect tokens that grant access to private resources.
const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('hex');
console.log(token);
64 hexadecimal characters representing 32 random bytes
Every run produces a different token. A 32-byte token contains 256 bits of random data.
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.
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.
A UUID is a universally unique identifier. Node.js provides
randomUUID() for generating a random version 4 UUID.
const crypto = require('crypto');
const id = crypto.randomUUID();
console.log(id);
e.g. 123e4567-e89b-42d3-a456-426614174000
Your UUID will normally be different every time you run the program.
Node.js provides timingSafeEqual() to compare
equal-length byte sequences in a way designed to avoid
timing-based information leaks.
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);
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.
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.
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.
| 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. |
We can create a reusable function that generates a SHA-256 hash for any text value.
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.
crypto module.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.
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?