crypto module
The crypto module is a built-in Node.js module that provides cryptographic functionality. It supports hashes (MD5, SHA-1, SHA-256), ciphers (AES, DES), signing (RSA, ECDSA), key derivation (PBKDF2, scrypt), and secure random generation. This module is the foundation for implementing security features in Node.js applications.
Syntax
const crypto = require('crypto'); // CommonJS
import crypto from 'crypto'; // ES modules (Node.js 19+)
import { createHash } from 'crypto'; // named imports
Key Functions and Classes
The crypto module provides several categories of functionality.
Hashing
Create hash digests with createHash:
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('plaintext-password');
const digest = hash.digest('hex');
console.log(digest);
// 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
Supported algorithms: 'md5', 'sha1', 'sha256', 'sha512', 'sha3-256', etc.
Output encodings: 'hex', 'base64', 'latin1', 'buffer'.
HMAC (Hash-based Message Authentication Code)
HMAC adds a secret key to the hashing process:
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('message');
const signature = hmac.digest('base64');
console.log(signature);
Ciphers and Decipher
Encrypt and decrypt data with symmetric algorithms:
const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32); // 256-bit key
const iv = crypto.randomBytes(16); // 128-bit IV
// Encrypt
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('secret message', 'utf8', 'hex');
encrypted += cipher.final('hex');
// Decrypt
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted); // "secret message"
Key Derivation
Derive keys from passwords using PBKDF2:
const crypto = require('crypto');
const password = 'my-password';
const salt = crypto.randomBytes(16);
crypto.pbkdf2(password, salt, 100000, 64, 'sha512', (err, derivedKey) => {
console.log(derivedKey.toString('hex'));
});
Or with scrypt (memory-hard):
const { scrypt } = require('crypto');
const { promisify } = require('util');
const scryptAsync = promisify(scrypt);
async function hashPassword(password) {
const salt = crypto.randomBytes(16);
const derivedKey = await scryptAsync(password, salt, 64);
return salt.toString('hex') + ':' + derivedKey.toString('hex');
}
Secure Random Generation
Generate cryptographically secure random values:
const crypto = require('crypto');
// Random bytes
const bytes = crypto.randomBytes(16);
console.log(bytes.toString('hex'));
// Random integer in range
const number = crypto.randomInt(1, 100);
console.log(number);
Timing-Safe Comparison
Compare values in constant time to prevent timing attacks:
const crypto = require('crypto');
const safeCompare = crypto.timingSafeEqual(
Buffer.from('expected'),
Buffer.from('received')
);
console.log(safeCompare); // false
WebCrypto API (Node.js 18+)
Node.js 18 introduced the WebCrypto API as crypto.webcrypto:
const { subtle } = crypto.webcrypto;
async function sha256(message) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await subtle.digest('SHA-256', msgBuffer);
return Array.from(new Uint8Array(hashBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
This API follows the browser WebCrypto standard.