Computer Science

Encryption

Symmetric for speed, asymmetric for handshake — together they're TLS

Encryption transforms data so only those with the key can read it. Symmetric encryption uses one shared key (fast, AES); asymmetric uses a public/private key pair (slow, RSA or elliptic curves). Real systems combine them — asymmetric for the handshake to exchange a symmetric session key, then symmetric for the bulk data. That's exactly how HTTPS, SSH, and end-to-end messaging work.

  • Symmetric standardAES-256 (~10⁷⁷ keys — uncrackable by brute force)
  • Asymmetric standardRSA-2048+, ECC (Curve25519, P-256)
  • Bulk cipher speedAES-NI hardware: 10+ GB/sec per core
  • RSA vs ECC at 128-bit securityRSA-3072 vs ECC-256 — ECC keys are 12× smaller
  • Hash for integritySHA-256, SHA-3, BLAKE3
  • Quantum threatShor's algorithm breaks RSA/ECC; AES needs key doubling

Interactive visualization

Press play, or step through manually. The visualization is yours to drive — try it before reading on.

Open visualization fullscreen ↗

Watch the 60-second explainer

A condensed visual walkthrough — narrated, captioned, under a minute.

Symmetric vs asymmetric encryption

SymmetricAsymmetric
Number of keysOne shared keyKey pair (public + private)
SpeedVery fast — GB/sec on modern hardwareSlow — KB/sec, ~1000× slower than symmetric
Key size for 128-bit securityAES-128: 16 bytesRSA: 384 bytes, ECC: 32 bytes
Key distributionHard — must share key in advanceEasy — publish public key
Best forBulk data encryptionKey exchange, digital signatures
StandardsAES (Rijndael), ChaCha20RSA, ECDSA, Ed25519, X25519
Quantum resistanceReduced (Grover): AES-256 → 128-bit post-quantumBroken (Shor): all current algorithms

The key-distribution gap is what motivated asymmetric encryption (Diffie-Hellman 1976, RSA 1977). Two parties who've never met can establish a secure channel — impossible with symmetric alone.

Hybrid encryption — how every real system works

Asymmetric is too slow for bulk data; symmetric requires a shared key. Hybrid encryption combines both:

  1. Generate a random symmetric session key. Pure randomness — unique per session.
  2. Encrypt the bulk data with the symmetric key. AES-GCM or ChaCha20-Poly1305. Fast, secure.
  3. Encrypt the symmetric key with the recipient's public key. Now only the recipient (with the matching private key) can recover the session key.
  4. Send (encrypted session key, encrypted message) together. The recipient's private key decrypts the session key, which then decrypts the message.

TLS does this on every HTTPS connection. Signal, WhatsApp, GPG, and S/MIME do it for messages. The asymmetric layer handles trust and key distribution; the symmetric layer handles speed and bulk.

AES — the workhorse symmetric cipher

AES (Advanced Encryption Standard) was selected by NIST in 2001 from a public competition. Block cipher: encrypts 128-bit blocks with a 128, 192, or 256-bit key. Modern CPUs include AES-NI instructions that run AES at 10+ GB/sec per core — effectively free for any reasonable workload.

The cipher itself isn't used directly — it's wrapped in a "mode of operation" that defines how to chain blocks together:

  • ECB (Electronic Codebook). Each block encrypted independently. Insecure — identical plaintext blocks produce identical ciphertext, leaking patterns. Never use for anything beyond textbook examples.
  • CBC (Cipher Block Chaining). Each block XORed with the previous ciphertext. Better than ECB. Vulnerable to padding-oracle attacks if not paired with a MAC.
  • CTR (Counter). Encrypts a counter; XORs with plaintext. Stream-like, parallelizable.
  • GCM (Galois/Counter Mode). CTR + Galois-field MAC. Authenticated encryption — provides integrity AND confidentiality. The modern default.

For new systems: AES-256-GCM or ChaCha20-Poly1305 (alternative based on different math, faster on devices without AES-NI like older mobile chips).

RSA vs ECC at equivalent security

Security levelRSA key sizeECC key sizeWhy ECC wins
80-bit (legacy)1024 bits160 bits6× smaller
112-bit2048 bits224 bits9× smaller
128-bit (current standard)3072 bits256 bits12× smaller
192-bit7680 bits384 bits20× smaller
256-bit (top)15360 bits512 bits30× smaller

Smaller keys mean faster operations, less bandwidth, less memory. ECC is the modern default for new systems. RSA persists for legacy compatibility — every browser still supports it, every CA still issues RSA certificates.

Hashing — adjacent but different

A hash function produces a fixed-size digest from arbitrary input. Common modern hashes:

  • SHA-256 — 256-bit digest, the workhorse. Used everywhere from Git to Bitcoin.
  • SHA-3 (Keccak) — different math from SHA-2 family, hedge against future SHA-2 attacks.
  • BLAKE3 — newer, much faster (10+ GB/sec), parallelizable. Used by Cargo, Cosmos, Backup tools.

Cryptographic hashes have three properties: preimage resistance (hard to find input matching a given output), second-preimage resistance (hard to find a different input with the same output), collision resistance (hard to find any two inputs with the same output). MD5 and SHA-1 are broken — cryptographic collision attacks exist. Don't use them for security.

Important: hashes are NOT encryption — there's no key, no decryption. Hashing transforms data one-way; encryption is reversible with the right key.

JavaScript: encryption with Web Crypto

// AES-GCM symmetric encryption
async function encryptAES(plaintext, key) {
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV for GCM
  const data = new TextEncoder().encode(plaintext);
  const ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key,
    data
  );
  return { iv, ciphertext };
}

async function decryptAES(ciphertext, key, iv) {
  const plaintext = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv },
    key,
    ciphertext
  );
  return new TextDecoder().decode(plaintext);
}

// Generate a 256-bit AES key
const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 256 },
  true,
  ['encrypt', 'decrypt']
);

// Generate an ECDSA key pair for signing
const keyPair = await crypto.subtle.generateKey(
  { name: 'ECDSA', namedCurve: 'P-256' },
  true,
  ['sign', 'verify']
);

// Sign a message
const message = new TextEncoder().encode('hello world');
const signature = await crypto.subtle.sign(
  { name: 'ECDSA', hash: { name: 'SHA-256' } },
  keyPair.privateKey,
  message
);

// Verify
const valid = await crypto.subtle.verify(
  { name: 'ECDSA', hash: { name: 'SHA-256' } },
  keyPair.publicKey,
  signature,
  message
);

Python: cryptography library

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.asymmetric.ec import generate_private_key, SECP256R1
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat

# Symmetric: AES-256-GCM
key = AESGCM.generate_key(bit_length=256)
aes = AESGCM(key)
nonce = b'\x00' * 12  # use os.urandom(12) in real code
ciphertext = aes.encrypt(nonce, b'secret message', associated_data=b'header')
plaintext = aes.decrypt(nonce, ciphertext, associated_data=b'header')

# Asymmetric: ECDSA on P-256
private_key = generate_private_key(SECP256R1())
public_key = private_key.public_key()

# Sign
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
signature = private_key.sign(b'message', ec.ECDSA(hashes.SHA256()))

# Verify
try:
    public_key.verify(signature, b'message', ec.ECDSA(hashes.SHA256()))
    print('valid signature')
except Exception:
    print('invalid signature')

Famous applied cryptography

  • HTTPS / TLS. ECDHE for forward-secret key exchange, ECDSA or RSA for server authentication, AES-GCM or ChaCha20-Poly1305 for bulk encryption. Hybrid done right.
  • Signal Protocol. Used by Signal, WhatsApp, Google Messages. Double Ratchet algorithm for perfect forward secrecy AND post-compromise security on every message. The gold standard for E2E messaging.
  • SSH. Public-key handshake to authenticate, then AES or ChaCha20 for the session. Per-server authorized_keys file lists allowed public keys.
  • Bitcoin / blockchain. ECDSA on secp256k1 for transaction signatures, SHA-256 for proof-of-work and hashing. No symmetric encryption used in Bitcoin's protocol — everything is signed and hashed but not encrypted.
  • PGP / GPG. Hybrid encryption for email and files. Asymmetric with RSA or ECC; symmetric with AES. Web of trust for key authentication (vs TLS's certificate authority model).

Common encryption mistakes

  • Rolling your own crypto. Don't. Every implementation bug becomes a CVE. Use a vetted library (libsodium, Python's cryptography, Web Crypto API). Even cryptography PhDs can't write secure crypto from scratch — the side-channel surface is too large.
  • Reusing nonces in stream ciphers. AES-GCM, ChaCha20-Poly1305, and CTR mode all break catastrophically if the same (key, nonce) pair encrypts two different plaintexts. The nonce can be a counter, but never repeat one for a given key.
  • Using ECB mode. Encrypts each block independently — identical plaintext blocks produce identical ciphertext, leaking patterns. The infamous "Linux penguin" image still recognizable after ECB encryption is the classic illustration.
  • Encryption without authentication. Symmetric encryption without a MAC (or AEAD mode like GCM) lets attackers tamper with ciphertext. Always use authenticated encryption — never CBC alone, never CTR alone.
  • Trusting downloaded code without verification. Code signing requires verifying signatures. Just downloading an app and assuming it's authentic skips the entire chain of trust.
  • Storing passwords with plain hashes. SHA-256(password) is breakable by GPU brute force in hours. Use bcrypt, scrypt, or Argon2 — slow hash functions designed specifically for passwords. The slowness is a feature.
  • Hardcoded keys in source code. Pushed to GitHub, scraped within hours. Use a secret manager (AWS Secrets Manager, HashiCorp Vault, environment variables). Never commit secrets to version control.

Frequently asked questions

What's the difference between symmetric and asymmetric encryption?

Symmetric uses ONE key — same key encrypts and decrypts. Fast (AES on modern CPUs hits 10+ GB/sec per core via AES-NI hardware), but both parties need the key beforehand. Asymmetric uses a key PAIR — public key encrypts, private key decrypts (or vice versa for signatures). Slow (RSA-2048 is ~1000× slower than AES) but solves the key-distribution problem — you can publish your public key and anyone can encrypt to you.

Why combine them in real systems?

Asymmetric is too slow for bulk data; symmetric requires a shared key beforehand. Hybrid systems use asymmetric for the handshake (exchange a randomly-generated symmetric session key) and symmetric for everything afterward. TLS, SSH, GPG, and Signal all do this. You get the security of asymmetric key exchange and the speed of symmetric encryption.

Why is AES considered uncrackable?

AES-256 has 2²⁵⁶ ≈ 10⁷⁷ possible keys. Brute-forcing means trying half of them on average. At a trillion keys per second across a million machines (10²⁴ keys/sec), that's still 10⁵³ seconds — billions of times the age of the universe. Mathematically secure against brute force; only failures come from key management, side channels, or implementation bugs.

Is RSA broken? Should I use ECC?

RSA isn't broken at proper key sizes (2048+ bits), but it's slower than ECC for equivalent security. ECC achieves 128-bit security with 256-bit keys; RSA needs 3072-bit keys for the same. ECC is preferred for new systems — smaller keys, faster operations, less memory. RSA is still widely deployed for compatibility. Both are vulnerable to quantum computers (Shor's algorithm).

What about quantum computing — when does encryption break?

Shor's algorithm runs on a sufficiently large quantum computer would break RSA, DSA, and ECC. Current quantum computers are nowhere near the scale needed (millions of error-corrected qubits required; current state of the art is ~1000 noisy qubits). Estimates for "cryptographically relevant" quantum computers range from 10 years to never. NIST is standardizing post-quantum algorithms (CRYSTALS-Kyber for KEM, CRYSTALS-Dilithium for signatures); deployment is starting now. AES is less affected — Grover's algorithm gives quantum speedup but only halves the effective key size, so AES-256 still gives 128-bit post-quantum security.

What's perfect forward secrecy?

A property where compromising long-term keys doesn't expose past sessions. Achieved by deriving session keys from ephemeral key pairs that are discarded after each session. ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) provides forward secrecy in TLS — even if a server's private key leaks, traffic recorded earlier stays encrypted forever (assuming the ephemeral keys were truly destroyed). Mandatory in TLS 1.3.

Why hash before signing?

RSA and ECC signatures are limited in size (typically 256 bytes for RSA-2048, 64 bytes for ECDSA P-256). Hashing reduces an arbitrary-size message to a fixed-size digest, which then gets signed. Without hashing, signing a 1 MB document would require chunking and complex padding. With hashing, the signature operation is constant-cost regardless of message size. Also: hashes provide message integrity — any change to the message produces a different hash, invalidating the signature.