The Codex / JavaScript / crypto — Cryptography

crypto — Cryptography

Secure hashing, HMACs, random data, UUIDs, and encryption in Node.js — the crypto built-in module.

What it is, in plain English: The crypto module provides cryptographic functionality in Node.js. Use crypto.randomBytes() for cryptographically secure random data. Use crypto.randomUUID() for UUIDs. createHash() creates MD5, SHA-1, SHA-256 hashes. createHmac() creates signed hashes for API authentication. For passwords specifically, use scrypt or bcrypt (from npm) — never plain SHA hashes.

Secure random data and hashing

Never use Math.random() for security. It's not cryptographically secure. Always use crypto.randomBytes() or crypto.randomUUID() for anything security-related.

Secure random data

import { randomBytes, randomUUID, randomInt } from "crypto";

// Random bytes (for tokens, salts, keys):
const token = randomBytes(32).toString("hex");   // 64-char hex string
const salt  = randomBytes(16).toString("base64"); // 24-char base64 string

console.log("Token:", token);  // "a3f8c2..."
console.log("Salt:",  salt);

// UUID — universally unique identifier (v4):
const id = randomUUID();
console.log("UUID:", id);  // "110e8400-e29b-41d4-a716-446655440000"

// Random integer in range [min, max):
const roll = randomInt(1, 7);  // dice: 1-6
console.log("Dice:", roll);

Hashing — one-way fingerprinting

import { createHash } from "crypto";

// SHA-256 hash of a string:
function sha256(data) {
  return createHash("sha256").update(data, "utf-8").digest("hex");
}

console.log(sha256("hello"));  // "2cf24dba..." (always same for same input)
console.log(sha256("hello"));  // same
console.log(sha256("Hello"));  // completely different — case sensitive!

// SHA-256 of a file:
import { readFileSync } from "fs";
const fileHash = createHash("sha256")
  .update(readFileSync("document.pdf"))
  .digest("hex");
// Use to verify file integrity (checksums)

// Common hash algorithms:
// sha256  — most common, 256-bit output ✓
// sha512  — stronger, 512-bit output ✓
// sha1    — deprecated, collision-prone ✗
// md5     — broken for security, ok for checksums ✗

HMAC — signed hashes for authentication

import { createHmac, timingSafeEqual } from "crypto";

// HMAC = Hash + Secret Key → verifiable signature
const SECRET  = process.env.WEBHOOK_SECRET ?? "my-secret";
const payload = JSON.stringify({ event: "push", repo: "codex" });

// Sign:
const signature = createHmac("sha256", SECRET)
  .update(payload)
  .digest("hex");

console.log("Signature:", signature);

// Verify (ALWAYS use timingSafeEqual — prevents timing attacks):
function verifyHMAC(received, payload, secret) {
  const expected = createHmac("sha256", secret).update(payload).digest("hex");
  const a = Buffer.from(received, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);  // constant-time comparison
}

console.log(verifyHMAC(signature, payload, SECRET));  // true
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.