Cryptography sounds intimidating, but the core insight behind public key crypto is elegant and explainable without math. Once you understand the intuition, TLS, SSH, PGP, and JWT signatures all make sense as natural consequences.
The Problem: Sharing a Secret Over a Public Channel
Symmetric encryption — where both parties use the same key — works great when you can share the key in advance. But imagine you want to communicate securely with a web server you've never contacted before. You need to agree on an encryption key, but every message you send can be read by anyone on the network. How do you establish a shared secret in public?
This is the key exchange problem, and it stumped cryptographers for decades. The breakthrough came in 1976 when Whitfield Diffie and Martin Hellman published their paper introducing public key cryptography. (British intelligence had reached the same conclusion independently a few years earlier, but it wasn't disclosed until later.)
The Trapdoor Function Insight
flowchart LR
P["p = 7919<br/>q = 6173"] -- "easy: multiply" --> N["n = 48 884 587"]
N -- "hard: factor" --> Q{"?"}
Q -. "without trapdoor:<br/>computationally infeasible<br/>at 2048-bit scale" .-> P
classDef hard fill:#1f1f1f,stroke:#f87171,color:#e4e4e4;
classDef easy fill:#1f1f1f,stroke:#4ade80,color:#e4e4e4;
class N easy
class Q hard
Some mathematical operations are easy to do but hard to reverse. That's the key insight.
Multiplying two large prime numbers together is fast — even for primes with hundreds of digits, modern computers do it in microseconds. But if I give you only the result and tell you it's the product of two primes, finding those primes (factoring) takes an astronomical amount of time. There's no known algorithm that does this efficiently.
This is called a trapdoor function: easy in one direction, computationally infeasible in the other unless you know a secret shortcut (the "trapdoor").
Public key cryptography is built on trapdoor functions. The details of which function gets used depend on the algorithm, but the structure is always the same: you pick a hard mathematical problem, use properties of that problem to create a key pair, and the security relies on the intractability of the underlying problem.
RSA: The Classic Algorithm
RSA (Rivest–Shamir–Adleman, published in 1977) is built on prime factorization. Here's the intuition without the actual math:
- Pick two large prime numbers,
pandq. - Multiply them:
n = p × q. This is easy. - Use
p,q, and some number theory to derive a public key and a private key. - Publish the public key (
nand a related numbere). Keep the private key secret.
Anyone can encrypt a message using your public key. Decrypting requires knowing p and q — which means factoring n. For an RSA-2048 key, n is a 617-digit number. Factoring it is currently beyond any known computer. That's the security guarantee.
Modern RSA key sizes are 2048 or 4096 bits. 1024-bit RSA is considered broken and should not be used. The NIST guidelines on key management specify minimum key lengths for different security levels.
Public Key Encryption: Encrypt for a Recipient
flowchart LR
M["Plaintext: <br/>'Meeting at 9am'"] --> E[("Encrypt with<br/>recipient's<br/>public key 🔓")]
E --> C["Ciphertext<br/>(unreadable)"]
C -- transmit over public network --> D[("Decrypt with<br/>recipient's<br/>private key 🔑")]
D --> M2["Plaintext:<br/>'Meeting at 9am'"]
Att(("Attacker<br/>has public key<br/>but not private")) -. cannot decrypt .-> C
The usage model for public key encryption:
- You publish your public key — anyone can have it, it's not a secret.
- Someone wants to send you a private message — they encrypt it using your public key.
- Only you can decrypt it — because only you have the private key.
Think of the public key as a padlock you hand out freely. Anyone can snap it shut on a message. Only you have the key to open it.
In practice, public key encryption is slow — much slower than symmetric encryption. So real systems use a hybrid approach: generate a random symmetric key, encrypt the data with that (fast), then encrypt just the symmetric key with RSA (slow but it's a small payload). This is exactly what TLS does.
Digital Signatures: Sign with Private, Verify with Public
flowchart TB
subgraph Sign["Signing (you, with private key)"]
direction LR
D1[Data] --> H1[hash]
H1 --> P1["sign(hash, private_key)"]
P1 --> S1[signature]
end
subgraph Verify["Verification (anyone, with public key)"]
direction LR
D2[Data received] --> H2[hash]
S2[signature received] --> V[("verify(signature,<br/>public_key)")]
H2 --> V
V --> R{Match?}
R -- yes --> OK[Authentic + intact]
R -- no --> Bad[Tampered or wrong signer]
end
Signatures work in reverse: you sign with your private key, and anyone with your public key can verify it.
Here's the flow:
- You compute a hash of the data you want to sign.
- You apply a signing operation using your private key — that's the signature. (In RSA, this is mathematically analogous to encrypting the hash; in ECDSA it involves the private key and a random nonce.)
- The recipient verifies the signature using your public key, confirming it matches the hash of the received data.
- If verification passes, they know the data hasn't been altered and the signature came from the private key holder.
This proves two things: the data hasn't been tampered with (integrity), and it came from whoever controls that private key (authenticity). No one else could have produced that signature without the private key.
Sign: hash(data) → sign with private key → signature
Verify: signature + public key → confirm hash matches data
Digital signatures are how code signing works, how SSH host verification works, and how JWT RS256 tokens are verified.
Elliptic Curve Cryptography: Why Everything Moved to EC
RSA has a scaling problem. As computers get faster, you need larger keys to maintain security. A 2048-bit RSA key gives roughly 112 bits of security; a 3072-bit key gives 128 bits; a 4096-bit key gives roughly 140 bits. The key sizes grow much faster than the security increase.
Elliptic Curve Cryptography (ECC) uses a different trapdoor: the elliptic curve discrete logarithm problem. The details are more complex, but the payoff is dramatic — a 256-bit EC key gives roughly the same security as a 3072-bit RSA key.
Smaller keys mean:
- Faster handshakes (important for TLS)
- Less CPU usage
- Less bandwidth for certificates
This is why modern TLS certificates almost always use EC keys (specifically ECDSA), why SSH keys are now usually Ed25519 (another EC algorithm), and why modern JWTs prefer ES256 over RS256. The RFC for Ed25519 is surprisingly readable if you want the details.
Real-World Applications
TLS/HTTPS: Your browser and a web server perform a key exchange using EC Diffie-Hellman to establish a shared symmetric key. Certificates use ECDSA signatures to prove identity. See How TLS and HTTPS Work for the full handshake.
SSH: When you generate an SSH key pair, you get a private key (stays on your machine) and a public key (added to the server's authorized_keys). The server proves you're legitimate by verifying a challenge signature with your public key.
PGP/GPG: Email encryption and software signing. Public keys are shared via keyservers; private keys stay with the owner.
JWT RS256/ES256: JWTs signed with RS256 or ES256 are signed with an asymmetric private key. Any service with the public key can verify the token without being able to forge new ones — useful for microservices.
Hashing Is Not the Same Thing
Public key crypto involves hashing as a component (especially in signatures), but hashing and encryption are fundamentally different. Hashing is one-way and deterministic — you can't reverse a hash. Encryption is two-way — you can decrypt if you have the key. The Hash Generator tool is useful for exploring SHA-256, SHA-512, and MD5 hashes. For encoding data in transit, Base64 Encoder handles the encoding layer that often wraps cryptographic output.
Also worth reading: Encoding vs. Encryption vs. Hashing — these three terms get conflated constantly, and the distinction matters when you're reasoning about security.
Public key cryptography is one of those topics where the intuition makes it feel manageable even if the math is dense. The key pair model, the trapdoor insight, and the encrypt/sign duality cover 90% of what you need for practical work.
FAQ
Should I use RSA or ECDSA in 2026?
For new keys, prefer ECDSA P-256 or Ed25519. They give equivalent security at smaller sizes (256-bit Ed25519 ≈ 3072-bit RSA), faster handshakes, and lower CPU usage. RSA is still safe — RSA-2048 isn't broken — but it's a worse-by-default choice when modern alternatives exist. Use RSA only when you need to interoperate with old systems that don't support EC.
Is RSA-2048 still secure, or do I need RSA-4096?
RSA-2048 (about 112 bits of security) is still safe in 2026 against classical attacks and matches NIST recommendations through 2030. RSA-4096 buys you very little extra security but adds significant CPU cost, especially in TLS handshakes. Don't go below 2048; don't bother going to 4096 unless you have a specific compliance reason.
Why can't I just decrypt a digital signature with the public key to read the original data?
For RSA signatures, you actually can — but the "data" inside is just a hash, not the message itself. The signer hashes the data first, then signs the hash. ECDSA and Ed25519 don't even use the encrypt-with-private-key analogy; the signing operation is mathematically distinct from encryption. Either way, signatures don't conceal the original message; they prove who hashed it.
Will quantum computers break public key crypto?
A sufficiently large quantum computer running Shor's algorithm would break RSA, ECDSA, and EC Diffie-Hellman in polynomial time. Such a computer doesn't exist yet — current quantum hardware can't factor large numbers — but the threat is real enough that NIST standardized post-quantum algorithms (ML-KEM, ML-DSA) in 2024. TLS 1.3 already supports hybrid post-quantum key exchange in Chrome and Cloudflare.
What's the practical difference between encryption and signing?
Encryption is about confidentiality — keeping data secret from everyone except the holder of the decryption key. Signing is about authenticity and integrity — proving who created the data and that it wasn't modified. They use the same math (key pairs) but in opposite directions: encrypt-with-public/decrypt-with-private vs. sign-with-private/verify-with-public.
How big should my private key file be on disk?
A PEM-encoded RSA-2048 private key is about 1.7 KB. RSA-4096 is around 3.2 KB. ECDSA P-256 is about 250 bytes. Ed25519 is roughly 120 bytes. If your private key is much smaller than expected, the file may be truncated or in a different format. If it's much larger, it's probably encrypted with a passphrase.
Is it safe to share my public key in a git repo or public website?
Yes — public keys are designed to be shared. That's the whole point. The risk isn't disclosure; it's authenticity. An attacker can't decrypt anything with a public key, but if they trick someone into using their key instead of yours, they can read messages meant for you. That's why fingerprints, CT logs, and out-of-band verification matter.
Why do TLS and SSH use both asymmetric and symmetric crypto?
Asymmetric crypto is slow — RSA decryption is roughly 1,000× slower than AES. So real protocols use asymmetric only for the initial key exchange (to establish a shared secret in public) and then switch to symmetric encryption for the bulk data. The handshake is the slow part; everything after is fast AES-GCM or ChaCha20-Poly1305.