Modern Cryptography Cheat Sheet: Symmetric, Asymmetric, Hashing, Signatures — Which to Use?
Encrypt a file for a friend, sign an API request, store a password in a database — three scenarios, three different cryptographic primitives, and getting any one of them wrong is a vulnerability.
A lot of developers' mental model of cryptography stops at the word "encryption", which leads to the same set of mistakes again and again: encryption used where signatures were needed, plain AES used where AEAD was required, SHA-256 used where Argon2 belongs.
This article breaks the four core primitives of modern cryptography apart — symmetric encryption, asymmetric encryption, hashing, digital signatures — and ends with a single decision tree you can follow next time crypto code shows up in your day.
Four Primitives, Locked Down
| Primitive | Direction | Needs a Key? | Typical Use | Speed |
|---|---|---|---|---|
| Symmetric encryption | Two-way | One shared key | Bulk data encryption | Fast |
| Asymmetric encryption | Two-way | Public + private key | Key exchange, small payloads | Slow |
| Hashing | One-way | None (HMAC excepted) | Integrity, fingerprinting | Very fast |
| Digital signatures | One-way | Private signs, public verifies | Authenticity + integrity | Medium |
Each solves a different problem. They are not interchangeable.
Symmetric Encryption
Core Idea
Both parties share the same key. Sender encrypts with it, receiver decrypts with it.
Mainstream Algorithms
| Algorithm | Recommendation | Notes |
|---|---|---|
| AES-128 / AES-256 | ⭐⭐⭐ | Industry standard, hardware-accelerated everywhere |
| ChaCha20 | ⭐⭐⭐ | Beats AES in pure software; mobile favorite |
| 3DES | ❌ | Deprecated; slow and weak |
| DES | ❌ | 56-bit key broken decades ago; banned |
| RC4 | ❌ | Multiple bias attacks; banned |
| Blowfish | ❌ | 64-bit block (birthday attack); banned |
Modes Are More Dangerous Than Algorithms
AES is just a block cipher — it encrypts 16 bytes at a time. To handle longer data you need a mode, and picking the wrong mode causes more vulnerabilities than picking the wrong algorithm.
| Mode | Status | Notes |
|---|---|---|
| ECB | ❌ Banned | Same plaintext → same ciphertext (the famous ECB penguin) |
| CBC | ⚠️ Use carefully | No integrity, padding oracle attacks |
| CTR | ⚠️ Use carefully | No integrity; reusing nonce leaks plaintext |
| GCM (AES-GCM) | ⭐⭐⭐ | Recommended; bundled authentication (AEAD) |
| ChaCha20-Poly1305 | ⭐⭐⭐ | Recommended; AEAD construction |
The Key Concept: AEAD
AEAD = Authenticated Encryption with Associated Data.
It bundles encryption and integrity in one operation — both "no one can read it" and "no one can change it" are handled together. Modern code should use AEAD only, not raw CBC/CTR.
AES vs ChaCha20
| Dimension | AES-256-GCM | ChaCha20-Poly1305 |
|---|---|---|
| Hardware acceleration | AES-NI on every modern CPU | No special instruction needed |
| Mobile performance | Medium (hardware-dependent) | Excellent (no hardware reliance) |
| Timing-attack resistance | Implementation-dependent | Side-channel-resistant by design |
| TLS 1.3 default | One of two | One of two |
Bottom line: server-side prefers AES-256-GCM (hardware acceleration); mobile / IoT prefers ChaCha20-Poly1305.
Asymmetric Encryption
Core Idea
Each party holds a key pair: public key is shared, private key is kept secret.
| Use | Encrypted With | Decrypted With | Solves |
|---|---|---|---|
| Encrypted communication | Recipient's public key | Recipient's private key | Confidentiality |
| Digital signatures | Sender's private key | Sender's public key | Authenticity |
Mainstream Algorithms
| Algorithm | Use | Key Size | Recommendation |
|---|---|---|---|
| RSA | Encryption / signatures / key exchange | At least 2048 bits | ⭐⭐ Still usable, aging |
| ECDH / ECDSA (NIST P-256/P-384) | Key exchange / signatures | 256-384 bits | ⭐⭐ Performant; some curve controversy |
| X25519 / Ed25519 | Key exchange / signatures | 256 bits | ⭐⭐⭐ Modern first choice |
| Post-quantum (Kyber / Dilithium) | Quantum-resistant | — | Experimental; worth tracking |
Critical Facts
- Asymmetric encryption is for small data only: RSA-2048 with OAEP-SHA256 caps a single encrypt call at 190 bytes (formula:
key_size_bytes - 2 - 2*hash_len) - The real practice is hybrid encryption: use asymmetric to exchange a symmetric key, then use symmetric for the bulk
- TLS works exactly this way: the handshake derives a session key via ECDHE, the rest of the traffic is AES-GCM
Common RSA Misuse
Also: RSA encryption requires OAEP padding, RSA signatures require PSS padding. PKCS1v15 is known-broken in both contexts.
Hashing
I covered hash internals in depth in the Hash Algorithms Comparison. The cheat-sheet conclusions:
| Scenario | Use |
|---|---|
| File integrity (no adversary) | SHA-256 / BLAKE3 |
| File integrity (anti-forgery) | SHA-256 / BLAKE3 |
| Password storage | Argon2id (first) / bcrypt (second) |
| API signing / webhook verification | HMAC-SHA256 |
| Generic fingerprint, cache keys | SHA-256 / BLAKE3 |
| ❌ Never use for security | MD5 / SHA-1 |
Digital Signatures
Core Idea
Digital signature = private key signs + public key verifies. Proves two things:
- Authenticity — the message really came from the signer
- Integrity — the message hasn't been altered since signing
Digital Signature vs Encryption vs HMAC
These three are conflated all the time:
| Primitive | Who Has the Key | What It Solves | Non-Repudiation? |
|---|---|---|---|
| Symmetric encryption | Both share the same key | Confidentiality | ❌ |
| HMAC | Both share the secret | Integrity + authenticity | ❌ (either side can sign) |
| Digital signature | Only sender has the private key | Integrity + authenticity | ✅ |
Key difference: with HMAC either side can sign — you can't prove to a third party "A sent this, not B". With a digital signature only A holds the private key, so anyone in the world can verify A's claim.
Algorithm Choice
| Algorithm | Recommendation | Notes |
|---|---|---|
| Ed25519 | ⭐⭐⭐ | Modern first choice — fast, short keys, side-channel resistant |
| ECDSA P-256 | ⭐⭐ | High compatibility; common in TLS certs |
| RSA-PSS-2048+ | ⭐⭐ | Compatibility-first; longer keys/signatures |
| RSA-PKCS1v15 | ⚠️ | Still around for legacy reasons; PSS is strictly better |
| ECDSA P-384 / RSA-4096 | ⭐⭐ | Higher security tier |
Prefer Ed25519 for new projects — it's already SSH's default.
Common Uses
- HTTPS certificate signing (CAs sign your cert with their private key)
- Software package signing (apt, yum, npm provenance)
- JWT's RS256/ES256/EdDSA
- Blockchain transaction signing
- Webhook payload signing (GitHub / Stripe / Lark)
The Big Decision Tree
Pulling everything above into one map:
5 Crypto Decisions Developers Most Often Get Wrong
Mistake 1: Use AES but Forget AEAD
In 2026, AES_MODE_CBC deserves the same status as MD5 — avoid it if you can.
Mistake 2: Reusing nonce / IV
GCM, CTR, ChaCha20 all require the nonce to be unique under a given key, forever. Reuse it once and you leak plaintext.
Or use a counter-based nonce — but ensure persistence and uniqueness across restarts.
Mistake 3: Treating a Signature as Encryption
"I signed my token with HMAC-SHA256, so the user ID inside is hidden."
❌ HMAC is a signature, not encryption. Everyone can read the contents of the token; HMAC only ensures no one can change them.
If you need "no one can read it", you need encryption. JWE (JSON Web Encryption) is the encrypted variant of JWT.
Mistake 4: Generic Hash for Password Storage
General-purpose hashes are too fast — GPUs run billions per second. Passwords need a purpose-built algorithm (Argon2id / bcrypt). See the Hash Algorithms Comparison for the full story.
Mistake 5: Rolling Your Own Crypto
90% of cryptographic vulnerabilities come from "rolled by hand + missed an edge case":
- Timing attacks (using
==instead ofcompare_digest) - Nonce reuse
- Padding oracle
- Elliptic-curve points off-curve (malicious input)
Always use audited libraries:
| Language | Recommended Library |
|---|---|
| Python | cryptography (not pycrypto) |
| Node.js | crypto (built-in) / libsodium-wrappers |
| Go | crypto/... (built-in) / golang.org/x/crypto |
| Rust | ring / rustcrypto |
| Cross-language | libsodium (NaCl) — the modern crypto Swiss Army knife |
Avoid: OpenSSL EVP API (unless you really know it), and any "AES I implemented myself".
libsodium: One-Stop Modern Cryptography
If I could recommend only one library, it'd be libsodium (built on Daniel J. Bernstein's NaCl):
- Defaults are safe algorithms (XSalsa20-Poly1305 / X25519 / Ed25519 / Argon2id / BLAKE2b)
- API is designed so misuse is nearly impossible
- Bindings exist in almost every language
Quick Example
About 80% shorter than rolling OpenSSL by hand, and the defaults are current best practice.
A Note on Post-Quantum Cryptography
Quantum computing progress puts classical asymmetric algorithms (RSA / ECC) at future risk — quantum computers can break them in polynomial time.
NIST standardized the first batch of post-quantum algorithms in 2024:
| Algorithm | Use | Status |
|---|---|---|
| CRYSTALS-Kyber (ML-KEM) | Key encapsulation | Standardized |
| CRYSTALS-Dilithium (ML-DSA) | Signatures | Standardized |
| SPHINCS+ (SLH-DSA) | Signatures (hash-based) | Standardized |
What you should do today:
- Watch but don't urgently switch — practical quantum attacks are 10-15 years out
- Design new protocols with crypto agility (algorithms swappable)
- TLS 1.3 + hybrid KEM (X25519 + Kyber) is already enabled in parts of Chrome / Cloudflare
Summary
Pin this cheat sheet to your brain:
| Scenario | Use |
|---|---|
| Encrypt bulk data | AES-256-GCM / ChaCha20-Poly1305 |
| Negotiate a shared secret | X25519 (ECDHE) |
| Digital signatures | Ed25519 > ECDSA > RSA-PSS |
| Verify a message with a shared secret | HMAC-SHA256 |
| Password storage | Argon2id > bcrypt |
| File fingerprinting | SHA-256 / BLAKE3 |
| Generate API keys | 32 bytes random (don't hash anything) |
Three iron rules:
- Always use AEAD — never raw CBC/CTR
- Always use audited libraries — prefer libsodium
- Never roll your own crypto — unless you've published a thesis on it
After writing code, validate key parameters with the Hash Generator, Password Generator, and Token Generator — paired with a solid crypto library, you cover ~95% of day-to-day development needs.