Part I: Secrets · Chapter 1
Symmetric encryption: one shared key
In one sentence
Symmetric encryption scrambles data with one secret key, and only someone who holds that same key can turn the scrambled data back into readable text.
Who is this for
Level: Beginner
On this page
The idea
- Beginner
When you send a message over the internet, it does not travel straight to your friend. It passes through many computers on the way: your Wi-Fi router, your internet provider, data centres, and the other person’s provider. Any of them could copy it. You cannot stop people copying it. You can only make the copy useless to them.
That is what encryption does. It takes readable text, called plaintext, and scrambles it into nonsense, called ciphertext. Turning the nonsense back into readable text is called decryption.
The scrambling is controlled by a secret key. A key is not a password you remember. It is a long random number, usually written as a string of letters and digits, for example:
2756673dc44d7e786bd515a25b952597e29c9f4cd9e9a79ccee8cb82f231b28f
In symmetric encryption, the same key does both jobs. You encrypt with key K, and the person you write to decrypts with the same key K. “Symmetric” means the two sides are the same.
Three things follow from that.
- The method is public. The key is the secret. Everyone knows how the scrambling works. That is fine, because without the key the ciphertext stays scrambled.
- The key must be long and random. Someone without the key could try every possible key, one after another. This is called brute force. A key with two digits has only 100 possible values, so a computer finds it at once. A 256-bit key has about 10⁷⁷ possible values, far more than the number of atoms in the Earth (about 10⁵⁰). Nobody can try them all.
- Encryption does not stop copying. A spy can still copy your ciphertext, keep it and pass it on. Encryption only makes sure the copy tells them nothing, as long as the key stays secret.
How it really works
- Developer
- Expert
What is a symmetric cipher, exactly?
A cipher is the algorithm that encrypts and decrypts. Today almost everything uses the Advanced Encryption Standard (AES), defined by NIST in FIPS 197. AES is a block cipher: it scrambles one block of 128 bits (16 bytes) at a time, under a key of 128, 192 or 256 bits. The three versions are called AES-128, AES-192 and AES-256.
The other common choice is ChaCha20, a stream cipher from RFC 8439. It is fast on phones and small devices that have no AES hardware.
A block cipher alone only scrambles 16 bytes. To encrypt a real message you need a mode of operation that says how to chain the blocks together. The oldest mode, ECB, encrypts each block separately, so identical blocks of plaintext give identical blocks of ciphertext. Patterns leak through. Never use it.
Why is scrambling not enough?
Encryption hides the content, but on its own it does not stop someone changing the ciphertext on the way. With some older modes, an attacker can flip bits in the ciphertext and cause predictable changes in the decrypted text, without ever knowing the key.
Modern systems therefore use authenticated encryption with associated data (AEAD). The interface is defined in RFC 5116:
- Inputs to encrypt: the key, a nonce (a number used once), the plaintext, and optional “associated data” that is protected but not hidden, such as a header.
- Output: the ciphertext plus an authentication tag.
- Decryption: either returns the exact plaintext, or fails with an error. If the key is wrong, or one bit of the ciphertext, tag, nonce or associated data has changed, you get no plaintext at all.
The two AEADs you will meet most are AES-GCM (NIST SP 800-38D) and ChaCha20-Poly1305 (RFC 8439).
What does AES-256-GCM look like in bytes?
| Part | Size | Secret? |
|---|---|---|
| Key | 32 bytes (256 bits) | Yes |
| Nonce (also called IV) | 12 bytes (96 bits) | No, but it must never repeat under the same key |
| Ciphertext | Same length as the plaintext | No |
| Authentication tag | 16 bytes (128 bits) | No |
So the 25-byte message “Three ships sail at dawn.” becomes 41 bytes of ciphertext and tag, and the sender also sends the 12-byte nonce.
Why must a nonce never repeat?
SP 800-38D recommends 96-bit IVs (section 5.2.1.1) and states the rule plainly in section 8: the chance of ever using the same IV twice with the same key must be no greater than 2⁻³². NIST adds that this requirement is “almost as important as the secrecy of the key”. If a nonce repeats under one key, GCM loses its protection against forged messages, and the two ciphertexts leak information about each other.
There are two safe ways to choose nonces:
- A counter. Never repeats, as long as you never reset it. TLS 1.3 does this: each record’s nonce is the record’s 64-bit sequence number combined (by XOR) with a secret IV that both sides derive during the handshake (RFC 9846, section 5.3).
- Random 96-bit values. Simple, but section 8.3 of SP 800-38D then limits you to 2³² encryptions per key. After that, change the key.
How long does a key need to be?
Every extra bit doubles the number of possible keys. A 128-bit key has 2¹²⁸ possible values, about 3.4 × 10³⁸. A 256-bit key has about 1.2 × 10⁷⁷. Trying them all is not feasible with any computer we know how to build.
Key lengths only compare within one algorithm. NIST’s SP 800-57 Part 1 (Table 2) rates AES-128 at 128 bits of security, the same as a 3,072-bit RSA key or a 256-bit elliptic-curve key. A “256-bit key” means very different things for AES and for RSA.
Real failures almost never come from guessing a properly random key. They come from:
- keys made from a password or a timestamp instead of a secure random generator;
- repeated nonces;
- keys that leak: in source code, logs, backups or a laptop that was lost.
If you must start from a password, use a key derivation function made for passwords, such as PBKDF2 (NIST SP 800-132) or Argon2 (RFC 9106). They make each guess slow.
Where is symmetric encryption used?
Almost everywhere data is protected in bulk, because it is fast. Most modern processors have AES instructions built in.
- HTTPS. TLS 1.3 (RFC 9846) protects every record with an AEAD. Every TLS 1.3 implementation must support TLS_AES_128_GCM_SHA256 and should support TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256 (section 9.1).
- Disk and file encryption on laptops and phones, and encrypted backups and databases.
- Wi-Fi, VPNs and messaging apps.
In all of these, the symmetric key itself is set up by a different mechanism first. In HTTPS, a fresh key is agreed for every connection, as the chapter on key exchange explains. Symmetric encryption does the heavy lifting; other tools solve the problem of getting the key to both sides.
At work
- Developer
- IT ops
Make a key
A symmetric key is just random bytes from a secure random generator. OpenSSL prints 32 random bytes, the size of an AES-256 key, like this:
openssl rand -hex 32
2756673dc44d7e786bd515a25b952597e29c9f4cd9e9a79ccee8cb82f231b28f
Use openssl rand -base64 32 if a configuration file wants Base64. Treat the output like a password: never paste a real key into a chat, a ticket or a Git repository. Store it in a secrets manager or a key vault.
See the symmetric cipher in a real HTTPS connection
Every HTTPS connection uses a symmetric cipher for the actual data. You can see which one with openssl s_client (output from OpenSSL 3.2 against www.rfc-editor.org):
openssl s_client -connect www.rfc-editor.org:443 -servername www.rfc-editor.org -brief < /dev/null
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=rfc-editor.org
Hash used: SHA256
Signature type: ECDSA
Verification: OK
Server Temp Key: X25519, 253 bits
Read it like this:
Ciphersuite: TLS_AES_256_GCM_SHA384is the symmetric part: AES-256 in GCM mode protects every byte of the page. SHA-384 is used to derive the keys.Server Temp Key: X25519is how the two sides agreed the secret that the AES keys are derived from, without ever sending it. That is the subject of key exchange.Signature type: ECDSAis how the server proved who it is. See digital signatures.
Use a library, not the enc command, for authenticated encryption
openssl enc looks like the obvious tool, but it does not support authenticated modes:
openssl enc -aes-256-gcm -pbkdf2 -in notes.txt -out notes.enc
enc: AEAD ciphers not supported
The OpenSSL documentation says enc “does not support authenticated encryption modes like CCM and GCM, and will not support such modes in the future”. The modes it does offer, such as CBC and CTR, do not detect tampering. In code, use AES-GCM or ChaCha20-Poly1305 from a well-reviewed library. This is the Web Crypto API, which works the same in browsers and in Node.js:
const key = await crypto.subtle.generateKey(
{ name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit nonce, never reused with this key
const data = new TextEncoder().encode("Three ships sail at dawn.");
const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, data);
console.log(data.length, "bytes in,", ct.byteLength, "bytes out (ciphertext + 16-byte tag)");
const pt = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ct);
console.log(new TextDecoder().decode(pt));
25 bytes in, 41 bytes out (ciphertext + 16-byte tag)
Three ships sail at dawn.
When we changed one bit of the ciphertext, or decrypted with a different key, decrypt threw OperationError and returned nothing. That is AEAD doing its job: a wrong key never gives you “nearly right” text.
How fast is it?
On the laptop used to write this page, one processor core encrypted with AES-256-GCM at about 3.6 GB per second:
openssl speed -evp aes-256-gcm -seconds 1 -bytes 16384
The 'numbers' are in 1000s of bytes per second processed.
type 16384 bytes
AES-256-GCM 3652698.11k
Your numbers will differ, but the point holds: encryption is rarely the reason a system is slow. Turn it on.
What goes wrong in real systems
- A fixed or reused nonce. A hard-coded IV, or a counter that resets after a restart, breaks AES-GCM. Let the library generate nonces, or use a counter stored safely.
- Keys in the wrong place. Keys in source code, container images, environment dumps or log files are the most common leak. Keep them in a key vault or an HSM (see guarding the keys).
- One key for everything, forever. Give each system and each purpose its own key, and plan how to rotate it. If a key leaks, everything it ever protected is exposed, including old copies someone recorded earlier.
Common mistakes
- “Encrypted means locked away, so nobody can get it.” Encryption does not stop anyone copying the data. It makes the copy unreadable without the key. Access control and encryption are different tools.
- “If I can decrypt it, it must come from my partner.” Everyone who holds a shared key can encrypt with it. An AEAD tag shows that a key holder made the message, not which one. Proving who wrote something needs a digital signature.
- “A bigger key number is always stronger.” Only within the same algorithm. AES-128 is far stronger than a 1,024-bit RSA key. Compare security levels, not raw bit counts.
- “My password is my key.” Human passwords are short and guessable. Turn a password into a key only with a password-based key derivation function such as PBKDF2 or Argon2.
- “The nonce is public, so it does not matter.” It is public, but it must never repeat under the same key. Reuse breaks AES-GCM.
- “Hashing is a kind of encryption.” A hash has no key and cannot be reversed. See hashes and fingerprints.
Why it matters to the business
- Leader
Check yourself
Rosa encrypts her orders with AES-GCM using key K1. The harbour holds a different key, K2, and tries to decrypt. What happens?
RightNot quite The answer is B: Decryption fails and the harbour gets no plaintext
- What happened
- With the wrong key, AES-GCM decryption fails its authentication check and returns an error, not text.
- Why
- Symmetric encryption needs the same key on both sides. Knowing the algorithm is not enough, and an AEAD never returns half-right text.
- The rule
- One secret key encrypts and decrypts. Without that exact key, the ciphertext stays useless.
Show answer
Answer B Decryption fails and the harbour gets no plaintext
- What happened
- With the wrong key, AES-GCM decryption fails its authentication check and returns an error, not text.
- Why
- Symmetric encryption needs the same key on both sides. Knowing the algorithm is not enough, and an AEAD never returns half-right text.
- The rule
- One secret key encrypts and decrypts. Without that exact key, the ciphertext stays useless.
Eve, a spy on the network, copies all of Rosa's encrypted orders and keeps them. Rosa used AES-256-GCM with a random key that only she and the harbour hold. What has Eve gained?
RightNot quite The answer is B: Nothing readable, as long as the key stays secret
- What happened
- Eve has ciphertext only. Without the key she cannot turn it back into plaintext.
- Why
- Encryption does not stop copying. It makes the copy useless without the key. The key is never inside the ciphertext.
- The rule
- Assume the network is read. Confidentiality depends on the key staying secret, so if the key ever leaks, every old copy becomes readable.
Show answer
Answer B Nothing readable, as long as the key stays secret
- What happened
- Eve has ciphertext only. Without the key she cannot turn it back into plaintext.
- Why
- Encryption does not stop copying. It makes the copy useless without the key. The key is never inside the ciphertext.
- The rule
- Assume the network is read. Confidentiality depends on the key staying secret, so if the key ever leaks, every old copy becomes readable.
A developer encrypts every database row with AES-256-GCM, one key, and the same hard-coded 12-byte nonce for every row. What is the problem?
RightNot quite The answer is B: The nonce repeats under the same key, which breaks the protection GCM gives
- What happened
- Every row reuses the same key and nonce pair.
- Why
- NIST SP 800-38D requires that an IV is not repeated under one key. With reuse, GCM no longer protects against forgery and the rows leak information about each other.
- The rule
- Never reuse a nonce with the same key. Use a counter or a fresh random 96-bit nonce, and change the key before 2³² random nonces.
Show answer
Answer B The nonce repeats under the same key, which breaks the protection GCM gives
- What happened
- Every row reuses the same key and nonce pair.
- Why
- NIST SP 800-38D requires that an IV is not repeated under one key. With reuse, GCM no longer protects against forgery and the rows leak information about each other.
- The rule
- Never reuse a nonce with the same key. Use a counter or a fresh random 96-bit nonce, and change the key before 2³² random nonces.
Go deeper
- FIPS 197: Advanced Encryption Standard: the AES algorithm, block size and key sizes.
- NIST SP 800-38D: GCM, the IV rules (section 8) and the limit on random IVs (section 8.3).
- RFC 5116: the AEAD interface that TLS and many libraries use.
- RFC 8439: ChaCha20 and Poly1305, the main alternative to AES-GCM.
- NIST SP 800-57 Part 1 Rev. 5: key management, and Table 2 comparing security strengths across algorithms.
- RFC 9846, section 5: how TLS 1.3 protects each record with an AEAD and a per-record nonce.
- OpenSSL
encdocumentation: what the command does and does not support.
Short on time? The crash course covers this chapter and the next in Lesson 1: Secrets and the sharing problem.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.