Node.js Crypto Module: Certificates, Encryption, and Key Exchange

The node:crypto module in Node.js provides cryptographic functionality including hashing, HMAC, encryption/decryption, signing, and verifying. It acts as a wrapper around OpenSSL and offers classes such as Certificate, Cipheriv, Decipheriv, and DiffieHellman for secure data handling and key exchange.

Asymmetric Key TypesCertificate ClassCipheriv ClassOpenSSL Integration

~8 min read • Updated Dec 27, 2025

1. Cipheriv Methods


  • cipher.final([outputEncoding]): Returns remaining encrypted contents. After calling, the object cannot be reused.
  • cipher.update(data[, inputEncoding][, outputEncoding]): Encrypts data incrementally. Can be called multiple times until final().
  • cipher.getAuthTag(): Returns authentication tag in authenticated encryption modes (e.g., GCM).
  • cipher.setAAD(buffer[, options]): Sets Additional Authenticated Data (AAD).
  • cipher.setAutoPadding([autoPadding]): Enables or disables automatic padding.

2. Decipheriv Class


Used to decrypt data. Similar to Cipheriv, it supports update() and final() methods.


  • decipher.final([outputEncoding]): Returns remaining decrypted contents. Cannot be reused after calling.
  • decipher.update(data[, inputEncoding][, outputEncoding]): Decrypts data incrementally.
  • decipher.setAAD(buffer[, options]): Sets AAD for authenticated decryption.
  • decipher.setAuthTag(buffer): Provides authentication tag to verify ciphertext integrity.
  • decipher.setAutoPadding([autoPadding]): Manages padding during decryption.

3. Diffie-Hellman Key Exchange


The DiffieHellman class enables secure key exchange:


  • generateKeys(): Generates public/private keys.
  • computeSecret(otherPublicKey): Computes shared secret using another party’s public key.
  • getPrime() and getGenerator(): Returns algorithm parameters.
  • setPrivateKey() and setPublicKey(): Sets custom keys.

4. DiffieHellmanGroup


A simplified version of Diffie-Hellman using predefined modp groups (modp14, modp15, modp16, etc.). Keys cannot be changed after creation.


Examples


// Encrypting data with Cipheriv
let encrypted = cipher.update('text', 'utf8', 'hex');
encrypted += cipher.final('hex');

// Decrypting data with Decipheriv
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');

// Diffie-Hellman key exchange
const alice = createDiffieHellman(2048);
const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator());
const secretAlice = alice.computeSecret(bob.generateKeys());
const secretBob = bob.computeSecret(alice.generateKeys());

Conclusion


The Cipheriv and Decipheriv classes provide secure encryption and decryption, while DiffieHellman and DiffieHellmanGroup enable robust key exchange. Together, these features ensure secure communication and data protection in Node.js applications.


1. DiffieHellmanGroup


The DiffieHellmanGroup class works like Diffie-Hellman but does not allow changing keys after creation. It supports well-known modp groups such as modp14 through modp18.


const { createDiffieHellmanGroup } = require('node:crypto');
const dh = createDiffieHellmanGroup('modp16');

2. ECDH (Elliptic Curve Diffie-Hellman)


The ECDH class enables elliptic curve-based key exchange, offering stronger security compared to traditional DH.


const { createECDH } = require('node:crypto');
const alice = createECDH('secp521r1');
const bob = createECDH('secp521r1');
const aliceKey = alice.generateKeys();
const bobKey = bob.generateKeys();
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

Features


  • ECDH.convertKey(): Converts public keys to different formats (compressed/uncompressed).
  • ecdh.generateKeys(): Generates private and public keys.
  • ecdh.computeSecret(): Computes the shared secret.
  • ecdh.getPrivateKey() and ecdh.getPublicKey(): Retrieves keys.

3. Hash Class


The Hash class generates cryptographic digests of data. It can be used as a stream or with update() and digest() methods.


const { createHash } = require('node:crypto');
const hash = createHash('sha256');
hash.update('some data to hash');
console.log(hash.digest('hex'));

Features


  • hash.update(): Adds data to the hash.
  • hash.digest(): Produces the final hash output.
  • hash.copy(): Creates a copy of the current hash state.

4. Hmac Class


The Hmac class generates HMAC digests (hashes with a secret key). It works similarly to Hash but adds key-based security.


const { createHmac } = require('node:crypto');
const hmac = createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));

Features


  • hmac.update(): Adds data for HMAC calculation.
  • hmac.digest(): Produces the final HMAC output.

Conclusion


The DiffieHellmanGroup and ECDH classes enable secure key exchange, while Hash and Hmac provide robust tools for generating cryptographic digests. Together, they form the backbone of secure communication and data integrity in Node.js applications.


1. Hmac Class


The Hmac class generates HMAC digests (hashes with a secret key).


  • hmac.update(data[, inputEncoding]): Adds data for HMAC calculation.
  • hmac.digest([encoding]): Produces the final HMAC output. Once called, the object cannot be reused.

const { createHmac } = require('node:crypto');
const hmac = createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));

2. KeyObject Class


The KeyObject class represents symmetric or asymmetric keys securely. It is safer than using strings or Buffers directly.


  • KeyObject.from(key): Converts a CryptoKey to a KeyObject.
  • keyObject.export([options]): Exports keys in PEM, DER, or JWK formats.
  • keyObject.equals(otherKeyObject): Compares two keys.
  • keyObject.type: Indicates the type ('secret', 'public', or 'private').
  • keyObject.symmetricKeySize: Size of symmetric keys in bytes.

3. Sign Class


The Sign class generates digital signatures.


  • sign.update(data): Adds data to be signed.
  • sign.sign(privateKey[, outputEncoding]): Produces a signature using a private key.

const { generateKeyPairSync, createSign } = require('node:crypto');
const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const sign = createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');

4. Verify Class


The Verify class validates signatures.


  • verify.update(data): Adds data for verification.
  • verify.verify(publicKey, signature): Verifies a signature using a public key.

const { generateKeyPairSync, createVerify } = require('node:crypto');
const { publicKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const verify = createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));

5. X509Certificate Class


The X509Certificate class encapsulates X509 certificates and provides read-only access to their properties.


  • x509.ca: Indicates if the certificate is a Certificate Authority (CA).
  • x509.checkEmail(email): Checks if the certificate matches an email address.
  • x509.checkHost(name): Checks if the certificate matches a hostname.
  • x509.checkIP(ip): Checks if the certificate matches an IP address.

const { X509Certificate } = require('node:crypto');
const x509 = new X509Certificate('{... pem encoded cert ...}');
console.log(x509.subject);

Conclusion


The Hmac, KeyObject, Sign, Verify, and X509Certificate classes in Node.js provide advanced cryptographic capabilities for secure key management, digital signatures, and certificate validation. These features strengthen the security of applications and ensure data integrity.


1. X509Certificate Class


The X509Certificate class provides methods and properties for inspecting and validating X509 certificates.


  • x509.checkIssued(otherCert): Checks if a certificate was potentially issued by another certificate.
  • x509.checkPrivateKey(privateKey): Verifies that the certificate’s public key matches a given private key.
  • x509.fingerprint / fingerprint256 / fingerprint512: Provides SHA-1, SHA-256, or SHA-512 fingerprints of the certificate.
  • x509.issuer / subject: Returns issuer and subject information.
  • x509.validFrom / validTo: Shows certificate validity dates.
  • x509.verify(publicKey): Verifies that the certificate was signed by a given public key.

2. Argon2 Functions


Argon2 is a password-based key derivation function designed to resist brute-force attacks. Node.js supports both asynchronous and synchronous implementations.


const { argon2Sync, randomBytes } = require('node:crypto');
const parameters = {
  message: 'password',
  nonce: randomBytes(16),
  parallelism: 4,
  tagLength: 64,
  memory: 65536,
  passes: 3,
};
const derivedKey = argon2Sync('argon2id', parameters);
console.log(derivedKey.toString('hex'));

3. Prime Checking


Node.js provides utilities to check if a number is prime, useful for cryptographic key generation.


  • crypto.checkPrime(candidate, options, callback): Asynchronous prime check using probabilistic methods.
  • crypto.checkPrimeSync(candidate, options): Synchronous prime check.

4. Cipher and Decipher


crypto.createCipheriv and crypto.createDecipheriv create encryption and decryption objects with specified algorithms, keys, and initialization vectors.


5. Diffie-Hellman and ECDH


crypto.createDiffieHellman and crypto.createECDH enable secure key exchange using either traditional or elliptic curve methods.


Examples


// Certificate verification
if (!x509.verify(otherCert.publicKey)) {
  throw new Error('Certificate not issued by otherCert');
}

// Argon2 password hashing
argon2('argon2id', parameters, (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));
});

Conclusion


The X509Certificate class, Argon2 functions, and prime-checking utilities provide advanced cryptographic capabilities in Node.js. These features enhance password security, certificate validation, and cryptographic key generation, ensuring stronger protection for modern applications.


1. Signature Verification


  • crypto.createVerify(algorithm[, options]): Creates a Verify object to validate signatures using a specified algorithm.
  • Supports digest algorithms like RSA-SHA256.

2. Key Encapsulation Mechanisms (KEM)


  • crypto.encapsulate(publicKey): Generates a shared key and ciphertext using a public key.
  • crypto.decapsulate(privateKey, ciphertext): Recovers the shared key using a private key.
  • Supports RSA, EC, X25519, X448, and ML-KEM algorithms.

3. Diffie-Hellman


  • crypto.diffieHellman({ privateKey, publicKey }): Computes a shared secret using DH or ECDH keys.

4. Key Generation


  • crypto.generateKey(type, options, callback): Asynchronously generates symmetric keys (HMAC or AES).
  • crypto.generateKeySync(type, options): Synchronous version.
  • crypto.generateKeyPair(type, options, callback): Generates asymmetric key pairs (RSA, DSA, EC, DH).
  • crypto.generateKeyPairSync(type, options): Synchronous version.

5. Prime Generation


  • crypto.generatePrime(size[, options], callback): Generates pseudorandom prime numbers.
  • crypto.generatePrimeSync(size[, options]): Synchronous version.
  • Supports safe primes and custom conditions for DH.

6. Cipher and Curve Information


  • crypto.getCipherInfo(nameOrNid): Retrieves information about a cipher algorithm.
  • crypto.getCiphers(): Lists supported cipher algorithms.
  • crypto.getCurves(): Lists supported elliptic curves.
  • crypto.getHashes(): Lists supported hash algorithms.

7. Examples


// Signature verification
const verify = crypto.createVerify('SHA256');
verify.update('data');
console.log(verify.verify(publicKey, signature));

// RSA key generation
crypto.generateKeyPair('rsa', {
  modulusLength: 4096,
  publicKeyEncoding: { type: 'spki', format: 'pem' },
  privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: 'aes-256-cbc', passphrase: 'secret' }
}, (err, publicKey, privateKey) => {
  console.log(publicKey, privateKey);
});

Conclusion


Advanced functions in the crypto module such as createVerify, encapsulate/decapsulate, diffieHellman, and key generation utilities provide developers with powerful tools for secure communication and data protection. These features enable building applications that are resilient against modern cryptographic threats.


Written & researched by Dr. Shahin Siami