After this lesson, you will be able to: Choose the right cryptographic primitive for a task, pick a safe library (libsodium, Web Crypto, Python cryptography), and know what to never implement yourself.
The payoff lesson: turning cryptographic knowledge into safe engineering decisions. This lesson maps common tasks to the right primitive, recommends vetted libraries, and gives the hard rules about what developers must never build themselves.
Encrypt data at rest or in transit: authenticated symmetric encryption (AES-256-GCM or ChaCha20-Poly1305). Store passwords: a slow salted hash (Argon2id, bcrypt, scrypt), never a plain hash. Verify a download or detect tampering: a hash (SHA-256) or, with a shared secret, HMAC. Prove authorship: a digital signature (Ed25519, ECDSA, RSA). Agree on a shared key over an insecure channel: ECDH (ephemeral for forward secrecy). Generate tokens or keys: a cryptographically secure random generator, never Math.random.
libsodium (NaCl) is the gold standard: it exposes a small set of hard-to-misuse, high-level functions with safe defaults, available in most languages. The Web Crypto API (crypto.subtle) is built into browsers and Node for standard primitives. Python's cryptography library provides both safe high-level recipes (Fernet) and lower-level primitives. Whatever you pick, prefer high-level, misuse-resistant APIs over assembling primitives by hand.
Tokens, keys, and IVs must come from a cryptographically secure source, never Math.random.
// WRONG: Math.random is not cryptographically secureconst badToken = Math.random().toString(36); // predictable, do not use// RIGHT (browser/Node Web Crypto)const bytes = crypto.getRandomValues(new Uint8Array(32));const token = Buffer.from(bytes).toString("hex");// RIGHT (Node)import { randomBytes } from "crypto";const secret = randomBytes(32).toString("hex");
Pick one.
Using Math.random for anything security-relevant. Assembling low-level primitives instead of using a high-level safe API. Inventing a custom scheme. Storing keys in code or config committed to Git. Using a fast hash for passwords. Reusing nonces. Not rotating keys. Copying crypto code from a random blog without understanding it. When unsure, reach for libsodium's high-level functions.
Sign in and purchase access to unlock this lesson.