Cryptography

Cryptography protects data from unauthorized access, verifies that messages haven't been tampered with, and confirms the identity of communicating parties. You don't need to implement cryptographic algorithms — that's almost always a mistake — but understanding what they do and when to use them is essential.

Symmetric Encryption

Symmetric encryption uses a single key for both encryption and decryption. It's fast, efficient, and the right choice when both parties can securely share a key in advance.

AES-256-GCM is the standard. It provides both confidentiality (the data is unreadable without the key) and integrity (any tampering is detected). ChaCha20-Poly1305 is a strong alternative, particularly on hardware without AES acceleration.

The challenge with symmetric encryption is key distribution: how do you get the same key to both parties without someone intercepting it?

Asymmetric Encryption

Asymmetric encryption solves the key distribution problem by using a key pair — a public key anyone can have, and a private key only the owner holds. Data encrypted with the public key can only be decrypted with the private key.

RSA is widely deployed but being gradually replaced by elliptic curve alternatives. Ed25519 is the modern recommendation for digital signatures — fast, secure, and compact. ECDH (Elliptic Curve Diffie-Hellman) allows two parties to derive a shared symmetric key over an insecure channel.

In practice, asymmetric encryption is used to establish a shared key, then communication switches to faster symmetric encryption. This is exactly how TLS works.

Hashing

A hash function takes input of any size and produces a fixed-size output. It's a one-way operation — you can't recover the input from the hash.

SHA-256 is the general-purpose standard for data integrity checks, digital signatures, and content addressing. BLAKE3 is a faster modern alternative.

Password hashing is a separate discipline entirely. General-purpose hash functions are too fast — an attacker with a GPU can test billions of guesses per second. Password hashing algorithms like Argon2 and bcrypt are intentionally slow and memory-intensive, making brute-force attacks impractical.

HMAC (Hash-based Message Authentication Code) combines a hash function with a secret key to verify both integrity and authenticity. It answers: was this message created by someone who knows the key, and has it been modified?

TLS

Transport Layer Security (TLS) encrypts data in transit between clients and servers. TLS 1.3 simplified the protocol significantly — fewer round trips to establish a connection, and a reduced set of strong cipher suites that eliminates the need to choose between dozens of options.

TLS relies on certificates issued by trusted Certificate Authorities (CAs) to verify server identity. Let's Encrypt made this free and automated through the ACME protocol.

Common Pitfalls

Don't implement your own cryptography. Use well-audited libraries (libsodium, OpenSSL, the standard library of your language). Cryptographic code that appears to work can have subtle vulnerabilities that only emerge under adversarial conditions.

Don't use weak randomness. Cryptographic operations require cryptographically secure random number generators. Using Math.random() or similar non-cryptographic sources for key generation, tokens, or nonces is a critical vulnerability.

Don't hardcode secrets. Keys and credentials belong in a secrets manager or environment configuration, never in source code or container images. See application-config for how we handle secrets loading, and incident-response for rotation procedures when credentials are compromised.