Symmetric Encryption

Overview

One shared key: block ciphers, modes, and authenticated encryption.

Symmetric encryption is the workhorse of practical cryptography. The same secret key encrypts and decrypts, so it protects bulk data at rest (disk volumes, database columns, backups) and in transit (the actual payload inside TLS, SSH, and VPN tunnels). Getting it right matters because a single wrong default, a reused nonce, or an unauthenticated ciphertext can silently turn “encrypted” into “readable” or “forgeable”.

The three things you have to choose correctly

A working symmetric scheme is not one decision but three, and each has a safe default in 2026:

ChoiceWhat it isSafe default
CipherThe keyed permutation that scrambles a blockAES (see AES) or ChaCha20
ModeHow the cipher is applied across a whole messageAn AEAD (GCM or ChaCha20-Poly1305)
Key managementHow keys are generated, stored, rotatedRandom 256-bit keys from a CSPRNG, kept out of code

Most real breakage is not a broken cipher. AES has stood since 2001. Breakage comes from the mode (using ECB, or CBC without authentication) or from operational mistakes (reusing a nonce, hardcoding a key). The pages under this group walk through each layer.

AES and why you never design your own cipher

AES is a public, peer-reviewed standard that has survived two decades of the most concentrated cryptanalysis in history. Its safety comes precisely from that scrutiny. A cipher you invent has none of it, and the failure mode is invisible: it will happily produce scrambled-looking output that a specialist can unwind. This is rule zero of the whole foundation, never roll your own crypto. Use vetted primitives through vetted libraries.

You can confirm AES is available and generate a proper key with OpenSSL:

mkdir -p ~/crypto-lab && cd ~/crypto-lab
openssl list -cipher-algorithms | grep -i "AES-256-GCM"
openssl rand -hex 32

Expected output:

AES-256-GCM
9f2c1b7d4e6a08c35f1128a9de77b0c4a6132e8f5b90d1c2334455667788aabb

The 32 random bytes (64 hex characters) are a 256-bit key. Never type keys by hand and never derive them from passwords without a KDF (see Password Hashing for why raw passwords make terrible keys).

Why the mode of operation matters as much as the cipher

A block cipher only encrypts one fixed-size block (16 bytes for AES). The mode of operation glues that primitive across an arbitrary-length message, and the choice of glue leaks or protects your data. Electronic Codebook (ECB) encrypts each block independently, so identical plaintext blocks produce identical ciphertext blocks and the shape of your data shows through. This is the origin of the famous “ECB penguin” image, an encrypted picture where you can still see the penguin. The Modes Of Operation page reproduces it hands-on.

The lesson: never use ECB, and never use raw CBC or CTR without a separate integrity check. Prefer a mode that authenticates.

AEAD as the modern default

Authenticated Encryption with Associated Data (AEAD) does two jobs in one primitive: it hides the data (confidentiality) and it detects any tampering (integrity and authenticity). If even one bit of ciphertext is flipped, decryption fails loudly instead of returning garbage that an attacker chose. The two AEADs you will reach for are AES-GCM and ChaCha20-Poly1305, covered in Authenticated Encryption and ChaCha20-Poly1305.

cd ~/crypto-lab
echo "transfer 500 to account 12345" > msg.txt
KEY=$(openssl rand -hex 32)
IV=$(openssl rand -hex 12)
openssl enc -aes-256-gcm -K $KEY -iv $IV -in msg.txt -out msg.enc 2>/dev/null
echo "encrypted $(wc -c < msg.enc) bytes"

Expected output:

encrypted 30 bytes

(Note: the OpenSSL enc command line does not emit or check the GCM tag cleanly, which is exactly why you use a library binding in real code, not the CLI, for AEAD. The Authenticated Encryption page explains the tag handling in detail.)

Practical Guidance

  1. Default to an AEAD: AES-256-GCM where AES hardware exists, ChaCha20-Poly1305 otherwise. Do not hand-assemble a cipher plus a mode plus a MAC yourself.
  2. Never use ECB, and never use CBC or CTR without a MAC. If you see these in a codebase, treat them as a finding.
  3. Generate keys from a CSPRNG (openssl rand), never from a password directly. Use a KDF when a password is the source.
  4. Treat nonce and IV uniqueness as a hard requirement. A single nonce reuse under GCM is catastrophic (see Authenticated Encryption).
  5. Keep keys out of source code and images. Load them from a secrets manager or environment at runtime, and plan for rotation.
  6. Follow rule zero always: use audited libraries (libsodium, your language’s standard AEAD binding) rather than raw OpenSSL primitives in application code.