Cryptography for Engineers
Cryptography is the foundation of every secure system. TLS, SSH, JWTs, code signing, certificate pinning, end-to-end encryption — they all rely on a small set of cryptographic primitives. Most engineers use these primitives through libraries without understanding what they do. That works until something breaks: a certificate chain fails validation, a signature verification returns false when it should not, or someone asks you to choose between RSA-2048 and Ed25519 and you have no basis for the decision.
This page covers the primitives that matter in production: key exchange, digital signatures, certificate chains, and the post-quantum algorithms that will replace today's cryptography within the next decade.
Asymmetric Algorithm Comparison
Before diving deep, here is the landscape:
| Algorithm | Type | Key Size (128-bit security) | Signature Size | Speed | Status |
|---|---|---|---|---|---|
| RSA-3072 | Factoring | 3072-bit public key | 384 bytes | Slow | Legacy, still widely used |
| ECDSA (P-256) | Elliptic curve | 256-bit public key | 64 bytes | Fast | Standard, widely deployed |
| Ed25519 | Edwards curve | 256-bit public key | 64 bytes | Very fast | Modern default |
| X25519 | Montgomery curve | 256-bit | N/A (key exchange only) | Very fast | Modern DH default |
| Dilithium | Lattice-based | ~1.3 KB public key | ~2.4 KB | Moderate | NIST PQC standard |
The Modern Default
For new systems in 2026, use Ed25519 for signatures and X25519 for key exchange unless you have a specific compliance requirement mandating RSA or ECDSA. Ed25519 is faster, has smaller keys, avoids entire classes of implementation bugs, and is supported by OpenSSH, TLS 1.3, and every major crypto library.
RSA: The Factoring Problem
RSA, published in 1977 by Rivest, Shamir, and Adleman, is based on the difficulty of factoring the product of two large primes.
RSA Key Generation
- Choose two large primes
and (each ~1536 bits for RSA-3072) - Compute
(this is the modulus, part of the public key) - Compute
(Euler's totient) - Choose public exponent
such that and (typically ) - Compute private exponent
(modular inverse)
Public key:
RSA Operations
Encryption:
Decryption:
Signing:
Verification:
Where
Why RSA Is Slow
RSA operations involve modular exponentiation with 3072+ bit numbers. Even with optimizations (Chinese Remainder Theorem for decryption, small public exponent for encryption), RSA is roughly 1000x slower than symmetric encryption.
Benchmark (typical modern CPU):
RSA-2048 sign: ~1.5 ms
RSA-2048 verify: ~0.04 ms
Ed25519 sign: ~0.02 ms
Ed25519 verify: ~0.06 ms
AES-256-GCM: ~3 GB/sRSA Padding Matters
Never use "textbook RSA" (
- OAEP (Optimal Asymmetric Encryption Padding) for encryption
- PSS (Probabilistic Signature Scheme) for signatures
- Never use PKCS#1 v1.5 padding in new systems (Bleichenbacher attack)
Elliptic Curve Cryptography
Elliptic curves provide the same security as RSA with dramatically smaller keys. An EC key of 256 bits provides roughly the same security as a 3072-bit RSA key.
The Math (Simplified)
An elliptic curve over a finite field
Plus a special "point at infinity"
The key insight is point addition: given two points
The Elliptic Curve Discrete Logarithm Problem (ECDLP): Given
ECDSA vs Ed25519
| Feature | ECDSA (P-256) | Ed25519 |
|---|---|---|
| Curve | NIST P-256 (Weierstrass) | Curve25519 (Edwards) |
| Randomness needed for signing | Yes (fatal if broken) | No (deterministic) |
| Constant-time implementation | Hard to get right | Built into the design |
| Side-channel resistance | Requires careful implementation | Resistant by construction |
| Signature malleability | Malleable without normalization | Non-malleable |
| Performance | Fast | Faster |
| Adoption | TLS, Bitcoin (secp256k1), PKI | SSH, Signal, Wireguard, TLS 1.3 |
ECDSA's Fatal Flaw: Nonce Reuse
ECDSA requires a random nonce
Ed25519 avoids this entirely by deriving the nonce deterministically from the private key and message using a hash function.
Ed25519 Internals
Ed25519 uses a twisted Edwards curve:
where
Key generation:
- Generate 32 random bytes as seed
- Hash:
, take first 32 bytes, clamp (clear/set specific bits) to get scalar - Public key:
where is the base point
Signing message
- Compute
(deterministic nonce from second half of hash and message) - Compute
- Compute
where is the group order - Signature is
— 64 bytes
Verification: Check that
Diffie-Hellman Key Exchange
Diffie-Hellman (1976) allows two parties to establish a shared secret over an insecure channel. It is the foundation of TLS, SSH, and virtually every encrypted connection.
Classical DH (Finite Field)
The security relies on the Discrete Logarithm Problem: given
The Math
Alice and Bob agree on public parameters:
- A large prime
(at least 2048 bits) - A generator
of the multiplicative group modulo
Alice computes
Bob computes
An eavesdropper sees
ECDH (Elliptic Curve Diffie-Hellman)
Modern systems use X25519 (ECDH over Curve25519) instead of classical DH:
import { createECDH } from 'crypto';
// Alice
const alice = createECDH('prime256v1');
alice.generateKeys();
const alicePublic = alice.getPublicKey();
// Bob
const bob = createECDH('prime256v1');
bob.generateKeys();
const bobPublic = bob.getPublicKey();
// Both compute the same shared secret
const aliceSecret = alice.computeSecret(bobPublic);
const bobSecret = bob.computeSecret(alicePublic);
console.log(aliceSecret.equals(bobSecret)); // trueDH Is Vulnerable to Man-in-the-Middle
Plain Diffie-Hellman provides no authentication. An attacker can perform two separate DH exchanges — one with Alice and one with Bob — and relay modified messages between them. This is why DH is always combined with authentication (digital signatures, certificates) in protocols like TLS.
Digital Signatures
A digital signature proves three things:
- Authentication — The message was created by the claimed sender
- Integrity — The message was not altered in transit
- Non-repudiation — The sender cannot deny having sent the message
How Signing Works
Practical Example: Signing a JWT
import { createSign, createVerify, generateKeyPairSync } from 'crypto';
// Generate Ed25519 key pair
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
// Sign
const message = '{"sub":"user123","exp":1700000000}';
const sign = createSign('SHA512'); // Ed25519 ignores this, uses EdDSA internally
sign.update(message);
const signature = sign.sign(privateKey);
console.log(`Signature: ${signature.toString('base64')}`);
// Output: 64-byte Ed25519 signature
// Verify
const verify = createVerify('SHA512');
verify.update(message);
const isValid = verify.verify(publicKey, signature);
console.log(`Valid: ${isValid}`); // true
// Tamper with message
const verify2 = createVerify('SHA512');
verify2.update(message + 'tampered');
const isValid2 = verify2.verify(publicKey, signature);
console.log(`Valid after tampering: ${isValid2}`); // falseCertificate Chains and PKI
The Trust Problem
Digital signatures prove a message came from a specific key, but how do you know the key belongs to who you think it does? This is the key distribution problem, and Public Key Infrastructure (PKI) solves it using a hierarchy of trust.
X.509 Certificate Structure
An X.509 certificate binds an identity to a public key:
Certificate:
Data:
Version: 3
Serial Number: 04:e2:8a:...
Signature Algorithm: ecdsa-with-SHA384
Issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc
Validity:
Not Before: Jan 15 00:00:00 2026 GMT
Not After: Feb 14 23:59:59 2027 GMT
Subject: CN=*.example.com, O=Example Inc
Subject Public Key Info:
Algorithm: id-ecPublicKey (P-256)
Public Key: 04:a3:b5:...
X509v3 Extensions:
Subject Alternative Name:
DNS:*.example.com, DNS:example.com
Key Usage: Digital Signature
Extended Key Usage: TLS Web Server Authentication
Signature Algorithm: ecdsa-with-SHA384
Signature Value: 30:45:02:21:...Certificate Chain Validation
Validation steps:
- Chain building: Construct a path from leaf certificate to a trusted root
- Signature verification: Each certificate's signature is verified with its issuer's public key
- Validity period: Check that every certificate in the chain is within its validity window
- Revocation check: Query CRL (Certificate Revocation List) or OCSP (Online Certificate Status Protocol)
- Name matching: Verify the leaf certificate's SAN (Subject Alternative Name) matches the requested hostname
- Key usage: Verify the certificate is authorized for the intended purpose (e.g., TLS server auth)
Certificate Transparency
Certificate Transparency (CT) is a public audit log for certificates. Every CA must submit certificates to CT logs before issuance. This allows domain owners to detect misissued certificates:
# Check CT logs for your domain
curl -s "https://crt.sh/?q=%.example.com&output=json" | jq '.[0:5]'Certificate Pinning Is Risky
Certificate pinning (hardcoding expected certificates or public keys) prevents MITM attacks but creates operational nightmares. If the pinned certificate expires or you need to rotate keys, pinned clients break with no recovery path. HPKP (HTTP Public Key Pinning) was deprecated in Chrome 72 for this reason. Prefer Certificate Transparency monitoring over pinning.
Post-Quantum Cryptography
Quantum computers with sufficient qubits will break RSA, ECDSA, Ed25519, and Diffie-Hellman using Shor's algorithm. While large-scale quantum computers do not exist yet, the threat is real because of harvest now, decrypt later — adversaries can record encrypted traffic today and decrypt it once quantum computers arrive.
What Breaks and What Survives
| Algorithm | Quantum Impact | Timeline |
|---|---|---|
| RSA | Broken by Shor's algorithm | When ~4000 logical qubits exist |
| ECDSA / Ed25519 | Broken by Shor's algorithm | Same |
| Diffie-Hellman | Broken by Shor's algorithm | Same |
| AES-256 | Weakened to 128-bit (Grover's) | Still secure with larger keys |
| SHA-256 | Weakened to 128-bit (Grover's) | Still secure |
| HMAC | Unaffected | Secure |
NIST Post-Quantum Standards (2024)
NIST selected four algorithms after an 8-year evaluation:
Key Exchange / Encryption:
- ML-KEM (CRYSTALS-Kyber) — Lattice-based key encapsulation mechanism. Fast, small keys (~1.5 KB). The recommended default for post-quantum key exchange.
Digital Signatures:
- ML-DSA (CRYSTALS-Dilithium) — Lattice-based signatures. Moderate size (~2.4 KB signatures). General-purpose default.
- SLH-DSA (SPHINCS+) — Hash-based signatures. Larger but relies only on hash function security (most conservative choice).
- FN-DSA (FALCON) — Lattice-based, smaller signatures than Dilithium but harder to implement safely.
Lattice-Based Cryptography: The Intuition
Lattice problems work in high-dimensional spaces. The core hard problem is the Learning With Errors (LWE) problem:
Given a system of approximate linear equations:
Where
Without the error term, this is simple linear algebra (Gaussian elimination). With the error term, it becomes computationally intractable even for quantum computers.
Hybrid Key Exchange in TLS
The transition strategy is hybrid key exchange: combine a classical algorithm (X25519) with a post-quantum algorithm (ML-KEM-768). If either one is secure, the combined scheme is secure.
TLS 1.3 Hybrid Key Exchange:
Client → Server: X25519_public_key || ML-KEM-768_encapsulation_key
Server → Client: X25519_public_key || ML-KEM-768_ciphertext
Shared secret = HKDF(X25519_shared_secret || ML-KEM_shared_secret)Chrome and Firefox already support X25519+ML-KEM-768 hybrid key exchange since 2024.
# Check if a server supports post-quantum key exchange
openssl s_client -connect example.com:443 -groups X25519MLKEM768Migration Timeline
Start Now
Even if large quantum computers are a decade away, you should:
- Inventory all cryptographic dependencies in your systems
- Enable hybrid key exchange where your TLS stack supports it
- Avoid RSA in new systems — use Ed25519/X25519 (easier to migrate to PQ later)
- Monitor NIST standards and your library's PQ support
Practical Cryptographic Decisions
Decision Matrix for Common Scenarios
| Scenario | Recommended Algorithm | Why |
|---|---|---|
| TLS certificates | ECDSA P-256 or Ed25519 | Broad compatibility (ECDSA) or performance (Ed25519) |
| SSH keys | Ed25519 | Smallest keys, fastest, most secure |
| JWT signing | Ed25519 (EdDSA) | Deterministic, no nonce pitfalls |
| Code signing | Ed25519 or ECDSA P-256 | Ecosystem support dependent |
| Encrypting data at rest | AES-256-GCM | Symmetric, fast, authenticated |
| Key exchange | X25519 + ML-KEM-768 (hybrid) | Post-quantum safe |
| Password hashing | Argon2id | Not encryption — purpose-built KDF |
| API request signing | HMAC-SHA256 | Symmetric, simple, fast |
Generate Ed25519 Keys
# SSH key
ssh-keygen -t ed25519 -C "engineer@example.com"
# OpenSSL
openssl genpkey -algorithm Ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
# View the key
openssl pkey -in private.pem -text -nooutCommon Cryptographic Mistakes
| Mistake | Impact | Correct Approach |
|---|---|---|
| Using RSA-1024 | Factorable with current hardware | Minimum RSA-2048, prefer RSA-3072 or Ed25519 |
| ECB mode for block ciphers | Patterns in plaintext visible in ciphertext | Use GCM (authenticated encryption) |
| Custom crypto protocol | Almost certainly broken | Use TLS 1.3, libsodium, or NaCl |
| Storing encryption keys alongside data | Key compromise = data compromise | Use HSMs, KMS, or envelope encryption |
| Using MD5 or SHA-1 for signatures | Collision attacks demonstrated | SHA-256 minimum |
| Not validating certificate chains | MITM trivially possible | Use standard TLS libraries, do not disable verification |
| Reusing nonces in AES-GCM | Catastrophic — authentication completely broken | Use random nonces or counter-based nonces, never reuse |
Never Roll Your Own Crypto
The first rule of cryptography: do not implement your own. Use audited, well-maintained libraries: libsodium, OpenSSL, BoringSSL, or your language's standard crypto library. The history of cryptography is littered with systems broken not because the math was wrong, but because the implementation was subtly flawed.
Further Reading
- Symmetric vs Asymmetric Encryption — Foundation for this page
- Key Management — Production key lifecycle
- Encryption in Transit — TLS configuration
- TLS Handshake Deep Dive — Where these algorithms meet the network
- Hashing Algorithms — SHA-256, BLAKE3, and when to use which
- Serious Cryptography by Jean-Philippe Aumasson — The best practical cryptography book
- Real-World Cryptography by David Wong — Modern algorithms with code examples
- NIST Post-Quantum Cryptography Standards (FIPS 203, 204, 205)