A practical decision guide for choosing encryption algorithms across symmetric, asymmetric, hashing, and post-quantum categories. Includes comparison tables, performance benchmarks, and a text-based decision flowchart.
Choosing the wrong encryption algorithm is worse than choosing no encryption at all — it creates a false sense of security. This guide provides a structured approach to selecting the right algorithm for your specific use case, threat model, and performance constraints.
How to use this document: Start with the decision flowchart to narrow your options. Then consult the comparison tables for detailed trade-offs. The recommendations at the end provide specific algorithm choices for common scenarios.
Fundamental Categories
Before selecting an algorithm, understand the four categories and when each applies.
| Category | Purpose | Key Characteristic | Example Algorithms |
|---|
| Symmetric Encryption | Encrypting data (at rest or in transit) | Same key encrypts and decrypts | AES-256-GCM, ChaCha20-Poly1305, XSalsa20 |
| Asymmetric Encryption | Key exchange, digital signatures, encrypting for a recipient | Public/private key pair | RSA-OAEP, ECDH, Ed25519, X25519 |
| Hashing | Integrity verification, password storage | One-way function, no decryption | SHA-256, SHA-3, BLAKE3, Argon2 |
| Post-Quantum | Future-proofing against quantum computers | Resistant to Shor’s and Grover’s algorithms | ML-KEM (Kyber), ML-DSA (Dilithium), SLH-DSA (SPHINCS+) — see our post-quantum cryptography deep dive |
Decision Flowchart
Follow this text-based flowchart to determine which algorithm category and specific algorithm you need.
START: What are you trying to do?
│
├─► Encrypt data at rest (files, databases, storage)
│ │
│ ├─► Hardware supports AES-NI instructions?
│ │ ├─► YES → AES-256-GCM
│ │ └─► NO → ChaCha20-Poly1305
│ │
│ └─► Data size?
│ ├─► < 64 KB per operation → AES-256-GCM (single block efficient)
│ └─► Streaming / large files → AES-256-GCM-SIV or ChaCha20-Poly1305
│
├─► Encrypt data in transit (TLS, API calls, WebSocket)
│ │
│ └─► Use TLS 1.3 with:
│ ├─► AES-256-GCM (hardware-accelerated environments)
│ └─► ChaCha20-Poly1305 (mobile, software-only environments)
│
├─► Exchange keys securely between parties
│ │
│ ├─► Need post-quantum resistance?
│ │ ├─► YES → ML-KEM-768 (Kyber) + X25519 hybrid
│ │ └─► NO → X25519 (ECDH on Curve25519)
│ │
│ └─► Legacy compatibility required?
│ ├─► YES → ECDH P-256 or RSA-2048 (minimum)
│ └─► NO → X25519
│
├─► Sign data or verify authenticity
│ │
│ ├─► Need post-quantum resistance?
│ │ ├─► YES → ML-DSA-65 (Dilithium) or SLH-DSA (SPHINCS+)
│ │ └─► NO → Ed25519
│ │
│ └─► Legacy compatibility required?
│ ├─► YES → ECDSA P-256 or RSA-PSS-2048
│ └─► NO → Ed25519
│
├─► Hash data for integrity
│ │
│ ├─► Password hashing?
│ │ └─► Argon2id (always)
│ │
│ ├─► Content integrity / checksums?
│ │ ├─► Speed critical → BLAKE3
│ │ └─► Interoperability critical → SHA-256
│ │
│ └─► Blockchain / Merkle trees?
│ └─► SHA-256 or Keccak-256
│
└─► [End-to-end encrypted](/cryptography/end-to-end-encryption/) messaging
│
└─► Use [Signal Protocol](/cryptography/signal-protocol-deep-dive/) (or derivative):
├─► X25519 for key agreement
├─► Ed25519 for identity keys
├─► AES-256-GCM or ChaCha20-Poly1305 for message encryption
└─► Double Ratchet for forward secrecy
Symmetric Encryption Comparison
These algorithms encrypt and decrypt with the same key. Use symmetric encryption for bulk data encryption.
Algorithm Comparison
| Criteria | AES-256-GCM | AES-256-CBC | ChaCha20-Poly1305 | XSalsa20-Poly1305 | AES-256-GCM-SIV |
|---|
| Security Level | 256-bit | 256-bit | 256-bit | 256-bit | 256-bit |
| Mode | AEAD (authenticated) | Non-authenticated | AEAD (authenticated) | AEAD (authenticated) | AEAD (nonce-misuse resistant) |
| Nonce Size | 96-bit | 128-bit IV | 96-bit | 192-bit | 96-bit |
| Nonce Reuse Tolerance | Catastrophic (key+nonce reuse breaks auth) | IV reuse leaks patterns | Catastrophic | Better (larger nonce space) | Tolerant (reveals only duplicate plaintexts) |
| Hardware Acceleration | Yes (AES-NI) | Yes (AES-NI) | No (but fast in software) | No | Yes (AES-NI) |
| Software Performance | Fast with AES-NI; slow without | Moderate | Very fast (3x AES without AES-NI) | Very fast | Slightly slower than GCM |
| Max Message Size | ~64 GB per nonce | No practical limit | ~256 GB | ~256 GB | ~64 GB |
| Browser Support | Yes (Web Crypto API) | Yes (Web Crypto API) | No (Web Crypto API) | No (requires library) | No (requires library) |
| NIST Approved | Yes | Yes | No (but IETF standardized) | No | Yes |
| Recommended | Yes | No (use GCM instead) | Yes | Situational | Situational |
When to Choose What
| Scenario | Recommended Algorithm | Reasoning |
|---|
| Web application (browser-based) | AES-256-GCM | Native Web Crypto API support; no library dependency |
| Mobile app (iOS/Android) | ChaCha20-Poly1305 | Better performance on ARM without AES-NI |
| Server-side with Intel/AMD | AES-256-GCM | Hardware acceleration via AES-NI |
| Database field encryption | AES-256-GCM-SIV | Nonce-misuse resistance reduces risk of implementation errors |
| File encryption | AES-256-GCM or ChaCha20-Poly1305 | Depends on platform hardware |
| VPN / tunnel encryption | ChaCha20-Poly1305 | WireGuard default; excellent cross-platform performance |
Asymmetric Encryption and Key Exchange Comparison
These algorithms use public/private key pairs. Use them for key exchange, digital signatures, and encrypting data for specific recipients.
Key Exchange Algorithms
| Criteria | RSA-2048 | RSA-4096 | ECDH P-256 | X25519 | ML-KEM-768 (Kyber) |
|---|
| Security Level | ~112-bit | ~140-bit | ~128-bit | ~128-bit | ~192-bit (post-quantum) |
| Key Size (Public) | 256 bytes | 512 bytes | 64 bytes | 32 bytes | 1,184 bytes |
| Key Size (Private) | ~1,200 bytes | ~2,400 bytes | 32 bytes | 32 bytes | 2,400 bytes |
| Ciphertext / Shared Secret Size | 256 bytes | 512 bytes | 64 bytes | 32 bytes | 1,088 bytes |
| Key Generation Speed | Slow (~100ms) | Very slow (~500ms) | Fast (~1ms) | Very fast (<1ms) | Fast (~1ms) |
| Operation Speed | Slow | Very slow | Fast | Very fast | Fast |
| Quantum Resistant | No | No | No | No | Yes |
| NIST Approved | Yes | Yes | Yes | No (IETF) | Yes (FIPS 203) |
| Browser Support | Yes (Web Crypto) | Yes (Web Crypto) | Yes (Web Crypto) | No (requires library) | No (requires library) |
| Recommended for New Systems | No | No | Situational | Yes | Yes (hybrid with X25519) |
Digital Signature Algorithms
| Criteria | RSA-PSS-2048 | ECDSA P-256 | Ed25519 | ML-DSA-65 (Dilithium) | SLH-DSA-128s (SPHINCS+) |
|---|
| Security Level | ~112-bit | ~128-bit | ~128-bit | ~192-bit (post-quantum) | ~128-bit (post-quantum) |
| Public Key Size | 256 bytes | 64 bytes | 32 bytes | 1,952 bytes | 32 bytes |
| Signature Size | 256 bytes | 64 bytes | 64 bytes | 3,293 bytes | 7,856 bytes |
| Signing Speed | Moderate | Fast | Very fast | Fast | Slow |
| Verification Speed | Fast | Moderate | Very fast | Very fast | Slow |
| Deterministic | Optional | No (requires good RNG) | Yes | Yes | Yes |
| Quantum Resistant | No | No | No | Yes | Yes |
| Recommended | Legacy only | Interoperability | Yes (default choice) | Yes (post-quantum) | Situational |
Hashing Algorithm Comparison
| Criteria | SHA-256 | SHA-3-256 | BLAKE3 | BLAKE2b | Argon2id | bcrypt |
|---|
| Output Size | 256-bit | 256-bit | 256-bit (default, variable) | Up to 512-bit | Variable | 184-bit |
| Speed (software) | Fast | Moderate | Very fast (3x SHA-256) | Fast | Intentionally slow | Intentionally slow |
| Parallelizable | No | No | Yes (SIMD, multithreaded) | No | Yes (configurable) | No |
| Use Case | General integrity, TLS | Government compliance | File checksums, KDFs | General purpose | Password hashing | Password hashing (legacy) |
| Memory Hard | No | No | No | No | Yes (configurable) | No |
| GPU Resistance | Low | Low | Low | Low | High (memory-hard) | Moderate |
| NIST Approved | Yes | Yes | No | No | No (but OWASP recommended) | No |
| Recommended | Yes (interop) | Situational | Yes (performance) | Situational | Yes (passwords) | Legacy only |
Password Hashing Parameters (Argon2id)
| Security Level | Memory | Iterations | Parallelism | Time Target |
|---|
| Minimum | 64 MB | 3 | 4 | ~500ms |
| Recommended | 256 MB | 4 | 4 | ~1 second |
| High Security | 1 GB | 6 | 8 | ~3 seconds |
| Maximum | 4 GB | 8 | 8 | ~5 seconds |
Post-Quantum Readiness
Quantum computers threaten asymmetric cryptography (RSA, ECC, ECDH) via Shor’s algorithm. Symmetric algorithms (AES) and hashing functions (SHA) are weakened but not broken by Grover’s algorithm (requiring doubled key sizes). For enterprise readiness assessment, see our post-quantum migration readiness analysis.
Timeline Assessment
| Threat Level | Estimated Timeline | Action Required |
|---|
| Harvest Now, Decrypt Later | Now (active threat) | Implement hybrid PQ for data with >10-year confidentiality requirement |
| Cryptographically Relevant Quantum Computer (CRQC) | 2030-2040 (estimated) | Plan migration path for all asymmetric crypto |
| Quantum advantage for symmetric attacks | 2040+ (speculative) | AES-256 provides adequate margin |
NIST Post-Quantum Standards (Finalized)
| Standard | Algorithm | Category | Use Case |
|---|
| FIPS 203 | ML-KEM (Kyber) | Key Encapsulation | Key exchange, TLS handshake |
| FIPS 204 | ML-DSA (Dilithium) | Digital Signature | General-purpose signatures |
| FIPS 205 | SLH-DSA (SPHINCS+) | Digital Signature (hash-based) | Long-term signatures, conservative choice |
Hybrid Approach (Recommended)
For systems being built in 2026, implement hybrid key exchange that combines a classical and post-quantum algorithm:
Hybrid Key Exchange:
Classical: X25519 (or ECDH P-256 for compliance)
Post-Quantum: ML-KEM-768
Combined shared secret = KDF(X25519_secret || ML-KEM_secret)
Rationale:
- If ML-KEM is broken → X25519 still provides security
- If X25519 is broken by quantum → ML-KEM provides security
- Defense in depth against unknown vulnerabilities in either
Key Size Reference
| Algorithm Family | Minimum Acceptable | Recommended | High Security | Notes |
|---|
| AES (symmetric) | 128-bit | 256-bit | 256-bit | 128-bit still secure; 256-bit for quantum margin |
| RSA (key exchange) | 2048-bit | 3072-bit | 4096-bit | Being phased out; migrate to ECC or PQ |
| ECC (NIST curves) | P-256 | P-256 | P-384 | P-521 offers marginal benefit over P-384 |
| Curve25519 (X25519/Ed25519) | 255-bit (fixed) | 255-bit (fixed) | 255-bit (fixed) | Single key size by design |
| ML-KEM (Kyber) | ML-KEM-512 | ML-KEM-768 | ML-KEM-1024 | 768 recommended for general use |
| ML-DSA (Dilithium) | ML-DSA-44 | ML-DSA-65 | ML-DSA-87 | 65 recommended for general use |
Common Mistakes
| Mistake | Risk | Correct Approach |
|---|
| Using AES-ECB mode | Plaintext patterns visible in ciphertext | Use AES-GCM or AES-CTR with authentication |
| Reusing nonces with AES-GCM | Complete loss of authentication; potential key recovery | Use a counter or random nonce with uniqueness guarantee; consider GCM-SIV |
| Using MD5 or SHA-1 for integrity | Collision attacks are practical | Use SHA-256, SHA-3, or BLAKE3 |
| Using SHA-256 for password hashing | GPU brute-force feasible | Use Argon2id with high memory parameter |
| RSA key size < 2048 bits | Factorable with current resources | Minimum 2048; prefer 3072+ or migrate to ECC |
| Implementing crypto primitives from scratch | Implementation bugs lead to total compromise | Use audited libraries (libsodium, OpenSSL, Web Crypto API) |
| Static ECDH without ephemeral keys | No forward secrecy | Use ephemeral ECDH (ECDHE) |
| Encrypting without authenticating | Vulnerable to padding oracle and bitflip attacks | Always use AEAD modes (GCM, Poly1305) |
| Platform | Recommended Library | Algorithms Covered |
|---|
| Browser (JavaScript) | Web Crypto API (native) | AES-GCM, RSA, ECDH, ECDSA, SHA-256/384/512 |
| Browser (extended) | libsodium.js | ChaCha20-Poly1305, X25519, Ed25519, Argon2, BLAKE2b |
| Node.js | node:crypto (native) + libsodium | Full symmetric/asymmetric suite |
| Rust | ring, RustCrypto | AES-GCM, ChaCha20, Ed25519, X25519, SHA-2, BLAKE3 |
| Go | crypto/… (stdlib) | AES-GCM, ChaCha20, Ed25519, ECDH, SHA-256 |
| Python | cryptography (pyca) | Full suite |
| Java/Kotlin | Tink (Google) | AES-GCM, ECDH, Ed25519, hybrid encryption |
| iOS/macOS | CryptoKit (Apple) | AES-GCM, ChaCha20, P-256, Curve25519, SHA-256 |
| Android | Tink (Google) or Conscrypt | AES-GCM, ChaCha20, ECDH, Ed25519 |
| Post-Quantum | liboqs (Open Quantum Safe) | ML-KEM, ML-DSA, SLH-DSA |
Quick Reference: What Stealth Cloud Uses
For transparency, here is the cryptographic stack used by Stealth Cloud’s Ghost Chat:
| Layer | Algorithm | Rationale |
|---|
| Message encryption | AES-256-GCM | Web Crypto API native; hardware-accelerated; AEAD |
| Key derivation | HKDF-SHA-256 | Standard KDF for deriving session keys |
| Client key exchange | X25519 | Fast, constant-time, small keys |
| Session authentication | Ed25519 (via SIWE) | Deterministic signatures, wallet-native |
| Transport | TLS 1.3 | Cloudflare edge termination |
| Password hashing | N/A | No passwords in architecture |
| Content integrity | SHA-256 | Interoperability with Web Crypto API |
This guide is maintained by Stealth Cloud. Cryptographic standards evolve — verify all recommendations against current NIST, IETF, and OWASP guidance before implementation. This document does not constitute security advice for regulated systems.