Cryptography
Cryptography in Practice
Heartbleed: two years in production, 17% of internet servers, TLS private key leakage - all due to a single missing length check. Correct math, incorrect code.
- **Heartbleed 2014**: OpenSSL read 64 kB of arbitrary server memory - Google, Yahoo, and GitHub immediately revoked their certificates.
- **POODLE 2014**: SSLv3 downgrade attack forced the entire internet to disable SSLv3 within weeks.
- **ROBOT 2017**: Bleichenbacher's 1998 attack rediscovered in F5, Citrix, and Cisco products - facebook.com was vulnerable and signatures could be forged.
- **Logjam 2015**: 768-bit DH parameters (the nginx/Apache defaults) broken for ~$10,000. The NSA presumably decrypted all such connections.
libsodium: A Safe Cryptographic Library
libsodium is a modern cryptographic library designed to prevent developer mistakes. Its principle: high-level APIs hide unsafe details. No algorithm selection is required - only one recommended implementation is provided. It automatically applies best practices: nonce management, authenticated encryption, and constant-time comparisons. Bindings exist for C, Python, Node.js, Rust, Go, Java, PHP, and others.
Signal Protocol, WhatsApp, and Wire use libsodium or its predecessor NaCl. Key primitives: Curve25519/X25519 for DH, Ed25519 for signatures, ChaCha20-Poly1305 for AEAD, Argon2id for password hashing, BLAKE2b for hashing. sodium_memzero() provides secure memory zeroing (the compiler cannot optimize it away). sodium_memcmp() performs constant-time comparison. These critical details are handled automatically and correctly in libsodium.
Why does libsodium generate the nonce automatically rather than leaving it to the developer?
OpenSSL: Capabilities and Pitfalls
OpenSSL is the most widely deployed TLS/crypto library, but its complex API offers dozens of ways to make mistakes. Heartbleed (2014): a buffer over-read in the TLS heartbeat extension spent 2 years in production and affected ~17% of all internet servers. The cause: OpenSSL did not validate the length of heartbeat requests. Patched in OpenSSL 1.0.1g. The result: LibreSSL and BoringSSL (Google) - security-focused forks.
BoringSSL (Google) and LibreSSL (OpenBSD) are safer alternatives with a reduced attack surface. BoringSSL removed deprecated algorithms, SSL 2.0/3.0, and export-grade cryptography. It is used in Chrome and Android. Rustls is a TLS implementation in Rust: memory-safe and immune to the class of bugs that caused Heartbleed. Benchmarks show Rustls is 5-20% faster than OpenSSL for TLS 1.3. Cloudflare migrated part of its edge infrastructure to Rustls in 2023.
Why was Heartbleed so critical even though TLS encryption itself was working correctly?
Common Mistakes in Cryptographic Implementations
ECB mode is a classic mistake: each 16-byte block is encrypted independently. Identical plaintext blocks produce identical ciphertext blocks. Data structure remains visible through encryption (the famous 'ECB penguin'). Rule: never use ECB. Always use CBC with a random IV - or better yet, AES-GCM or ChaCha20-Poly1305. Nonce reuse with stream ciphers or CTR mode: C1 = P1 XOR K, C2 = P2 XOR K, so C1 XOR C2 = P1 XOR P2 - revealing the XOR of the plaintexts.
Padding Oracle: if a server returns different errors for 'wrong MAC' vs 'wrong padding', this creates an oracle for attack. Always use Encrypt-then-MAC (or AEAD) and return the same generic error message in both cases. Weak KDF: using SHA256(password) as a key allows offline brute-force attack. Always use Argon2id, bcrypt, or scrypt. IV/Nonce from a constant or timestamp: the IV must be cryptographically random. A deterministic IV opens the door to nonce-reuse attacks.
Why is using `random.randint` instead of `secrets.token_bytes` for key generation critically dangerous?
Real-World Cryptographic Vulnerabilities
POODLE (2014): attack on SSLv3 CBC padding oracle - browsers could be forced to downgrade to SSLv3 through connection errors. Fix: disable SSLv3 (TLS_FALLBACK_SCSV). BEAST (2011): attack on TLS 1.0 CBC via chosen-plaintext in a browser. CRIME/BREACH (2012-2013): attack on TLS compression - compressing plaintext before encryption leaks data through ciphertext size. Fix: disable TLS compression.
Mozilla SSL Configuration Generator (ssl-config.mozilla.org) produces safe nginx/Apache/HAProxy configurations. testssl.sh is a script that audits a TLS server against 100+ potential vulnerabilities. The OWASP Cryptographic Storage Cheat Sheet provides guidelines for secure storage. Survival rules: use high-level libraries (libsodium, Tink), do not invent cryptography, audit TLS configuration regularly, enable PFS, and disable deprecated algorithms and protocols.
Why do most real-world cryptographic attacks exploit protocol errors rather than mathematical weaknesses in primitives?
Secure Cryptography in Practice
- **libsodium**: high-level API, automatic nonce management, constant-time operations - the first choice for new projects.
- **OpenSSL**: powerful but dangerous; never disable verify_mode. BoringSSL and Rustls are safer alternatives.
- **Top mistakes**: ECB mode, nonce reuse, weak RNG (random vs secrets), non-constant-time MAC comparison, verify=False.
- **Practice**: Mozilla SSL Config Generator plus testssl.sh for auditing. Most attacks exploit protocols, not mathematics.
Related Topics
Practical cryptography integrates knowledge from the entire course - primitives, protocols, and their correct application.
- The TLS Protocol — Most practical attacks (POODLE, BEAST, Logjam) target TLS configuration, not its underlying primitives.
- Password Hashing — Argon2id from libsodium is the correct choice for password hashing against brute-force attacks.
- Side-Channel Attacks — Constant-time comparisons in libsodium protect against timing attacks adjacent to the Heartbleed class of vulnerabilities.
Вопросы для размышления
- If libsodium makes most decisions automatically, when does a developer still need to make cryptographic choices? What decisions can libsodium not make for them?
- Heartbleed was a buffer over-read in heartbeat. What process change would have caught this before it reached production for two years?
- Logjam broke 768-bit DH which was the nginx/Apache default. What does this imply about the security of cryptographic library defaults in general?