The crypto Module

The crypto module is Node's built-in toolkit for cryptography — creating hashes and HMAC signatures, generating secure random values, and safely deriving and comparing password hashes.

Learn The crypto Module in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll be able to fingerprint data with SHA-256, sign messages with HMAC, generate secure tokens and UUIDs, store passwords the right way with scrypt and a salt, and compare secrets safely with timingSafeEqual.

What You'll Learn in This Lesson

1️⃣ Hashing & HMAC

A hash turns any input into a fixed-size fingerprint. The same input always yields the same digest, the tiniest change yields a wildly different one, and you can't run it backwards. The pattern in Node is always createHash(algo).update(data).digest('hex') .

HMAC is a keyed hash: it mixes in a secret so only someone holding that key can produce or verify the signature. It's how services sign webhooks and API requests so the receiver can trust the message wasn't forged or altered.

2️⃣ Secure Randomness

Never use Math.random() for anything security-related — it's predictable. The crypto module gives you cryptographically strong randomness: randomBytes(n) for raw tokens and salts, randomUUID() for standard v4 IDs, and randomInt(min, max) for a fair integer in a range.

Because these values are random by design, the example checks properties of the output (length, format, range) rather than printing the exact bytes — that way the output is reproducible while the values stay genuinely random.

3️⃣ Passwords Done Right

This is the most important section. Never store a password as a plain SHA-256 hash — it's far too fast, so attackers can guess billions per second. Use a deliberately slow key-derivation function like scrypt (or pbkdf2 ), with a unique random salt per user so identical passwords never share a hash.

When you verify a login, re-derive the hash from the attempt and the stored salt, then compare with crypto.timingSafeEqual — a constant-time compare that won't leak how close a guess was. (We use a fixed salt here only so the demo output is reproducible; real code uses randomBytes .)

Your turn. The program below works once you fill in the two blanks marked ___ . Follow the 👉 hints, then run it and compare with the expected digest.

No blanks this time — just a brief and an outline. Write it yourself, run it, and check your output against the example in the comments. This ties together scryptSync , salts, and timingSafeEqual .

📋 Quick Reference — crypto

Practice quiz

What is a hash?

  • A reversible encryption of data
  • A random number generator
  • A one-way fingerprint that cannot be reversed
  • A compression format

Answer: A one-way fingerprint that cannot be reversed. A hash maps input to a fixed-size fingerprint; the same input always yields the same digest and you cannot reverse it.

What is the Node pattern for a SHA-256 hex digest?

  • createHash('sha256').update(data).digest('hex')
  • hash('sha256', data)
  • sha256(data).hex()
  • crypto.encrypt(data, 'sha256')

Answer: createHash('sha256').update(data).digest('hex'). The pattern is always createHash(algo).update(data).digest('hex').

What does HMAC add compared to a plain hash?

  • Reversibility
  • Compression
  • A timestamp
  • A secret key, so only key holders can produce or verify it

Answer: A secret key, so only key holders can produce or verify it. HMAC mixes a secret key into the hash, used to sign webhooks and API requests so the receiver can trust them.

Which function generates cryptographically strong random bytes?

  • Math.random()
  • crypto.randomBytes(n)
  • crypto.hash(n)
  • crypto.salt(n)

Answer: crypto.randomBytes(n). crypto.randomBytes(n) returns strong random data for tokens and salts; never use Math.random() for security.

How many hex characters does crypto.randomBytes(16).toString('hex') produce?

  • 32
  • 16
  • 64
  • 8

Answer: 32. Each byte becomes two hex characters, so 16 bytes produce a 32-character hex string.

Why must you NOT store passwords as a plain SHA-256 hash?

  • SHA-256 is reversible
  • SHA-256 cannot hash text
  • SHA-256 is too fast, so attackers can guess billions per second
  • SHA-256 needs a network connection

Answer: SHA-256 is too fast, so attackers can guess billions per second. Fast hashes let attackers brute-force quickly; use a slow KDF like scrypt or pbkdf2 instead.

What is a salt and why is it unique per user?

  • A secret shared by all users
  • Random data per password so identical passwords get different hashes
  • An encryption key
  • The hashing algorithm name

Answer: Random data per password so identical passwords get different hashes. A unique random salt makes every stored hash different and defeats precomputed rainbow tables.

Which function derives a slow password hash in the lesson?

  • crypto.createHash
  • crypto.randomUUID
  • crypto.createHmac
  • crypto.scryptSync

Answer: crypto.scryptSync. scrypt is a deliberately slow key-derivation function; the demo uses crypto.scryptSync(password, salt, 32).

Why compare secrets with crypto.timingSafeEqual instead of ===?

  • It is faster than ===
  • It compares in constant time, avoiding timing side-channel leaks
  • It works on strings only
  • It encrypts the inputs first

Answer: It compares in constant time, avoiding timing side-channel leaks. === can stop at the first differing byte, leaking timing info; timingSafeEqual always takes the same time.

When should you use createHash versus createHmac?

  • Always use createHash
  • createHmac for file integrity only
  • createHash for a plain fingerprint, createHmac when a shared secret is involved
  • They are interchangeable

Answer: createHash for a plain fingerprint, createHmac when a shared secret is involved. Use createHash for integrity or cache keys with no secret; use createHmac to prove a message came from a key holder.