Symmetric Encryption
- One key, shared. The same key encrypts and decrypts —
conventional cryptography, and the only kind
there was until 1976
- Fast: gigabytes per second on a laptop, with hardware support
- Its whole difficulty is in one question:
how did both sides get the key?
- n people who all want to talk pairwise need
n(n−1)/2 keys. For 1,000 people that is
499,500
The Symmetric Setting

The channel can be as public as you like. Everything rests on the two
copies of K — and the diagram has no arrow
for how they got there.
The Key Count, Drawn

Each line must be set up over a channel that is already secure.
The count grows with the square of the group — this is the wall public-key
cryptography was invented to climb.
Block and Stream
- Block cipher — encrypts a fixed-size
block, e.g. 128 bits at a time
- AES. Needs a mode to handle anything longer than one block
- Stream cipher — generates a keystream and
XORs it with the data
- ChaCha20. Naturally handles any length, byte by byte
- In modern practice the line is blurred: AES in counter mode
is a stream cipher built from a block cipher
A Short History of the Standard
| DES | 1977, 56-bit key. Broken by dedicated hardware in 1998, in days.
Dead |
| 3DES | DES three times, ~112-bit strength. Slow, 64-bit blocks.
Disallowed by NIST |
| AES | 2001, Rijndael, FIPS 197. 128-bit blocks, 128/192/256-bit keys.
The answer |
| ChaCha20 | The alternative, and faster where there is no AES hardware |
AES was chosen through a
public competition
with published analysis — Kerckhoffs's principle applied to the selection
process itself.
A Cipher Is Not Enough
- AES encrypts 16 bytes. Your message is not 16 bytes
- The mode of operation says how to chain
the blocks — and it is where the security is actually won or lost
- The obvious mode is to encrypt each block independently. That is called
ECB, and it is the most instructive mistake
in cryptography
Let us encrypt a picture with it.
Before

The raw pixels of this image, AES-128, one key, ECB mode.
After — This Is the Ciphertext

Every block is correctly encrypted with a strong cipher.
Identical plaintext blocks produce identical ciphertext blocks, so
the pattern survives.
The Same Image, CBC Mode

Same cipher, same key, same data. The only change is that each block is
XORed with the previous ciphertext first.
CBC and CTR, Drawn

CBC chains each block into the next, from a random
IV. CTR XORs in a
keystream made from (key, nonce) — a
nonce is a public number used once.
Modes Worth Knowing
| ECB | Each block alone. Never use it. Ever |
| CBC | XOR with the previous ciphertext. Needs a random IV; needs padding;
padding is attackable |
| CTR | Encrypt a counter, XOR with data. No padding, parallel, seekable |
| GCM | CTR plus authentication. This is the default answer |
- CBC needs an IV and CTR/GCM need a
nonce: not secret, but never repeated
under the same key
- Reuse a CTR/GCM nonce and you have reused a one-time pad.
Two messages, one keystream, both readable
Why the Nonce Must Not Repeat

No key recovery, no cryptanalysis — one XOR. This is the one-time pad used
twice, from the Foundations section, and it is why
nonce reuse is fatal rather than merely weak.
In the Wild: WEP, 2001
- Wi-Fi's first encryption: RC4 keyed with a shared key and a
24-bit IV, sent in the clear
- A busy access point runs out of IVs in under half a day; random IVs
repeat after about 5,000 packets. A repeated IV is
a repeated keystream — the diagram
before this one
- The same year, Fluhrer, Mantin and Shamir went further and recovered the
key itself from RC4's key schedule
- TJX's stores were still on WEP when intruders came in over their store
Wi-Fi: an estimated 45 million payment cards, reported in 2007
- The fix, WPA2: AES with a 48-bit packet counter that never repeats, and
a real MAC
Lecture 1's "reader on the lab wifi", with a published recipe.
Source:
Borisov, Goldberg, Wagner, Intercepting Mobile Communications
·
Fluhrer, Mantin, Shamir, Weaknesses in the Key Scheduling Algorithm of
RC4
·
Privacy Commissioner of Canada, TJX report
Hash Functions
You ran one in lecture 1: shasum. Here is what it promises.
- Any input, fixed-size output. No key.
Not encryption — there is nothing to reverse,
because information was thrown away
- Three properties, in increasing order of difficulty to achieve:
- Preimage — given h, you
cannot find any m with hash h
- Second preimage — given m, you
cannot find a different m′ with the same hash
- Collision — you cannot find
any pair that collides
- Collisions are the easiest to attack — the birthday paradox puts an
n-bit hash at only n/2 bits of collision resistance
The Three Properties, Drawn

Read left to right, the attacker is handed less and allowed to choose
more. That is why collisions fall first: SHA-1 lost collision resistance
and is still not preimage-broken.
The Avalanche
$ printf 'security' | shasum -a 256
5d2d3ceb7abe552344276d47d36a8175b7aeb250a9bf0bf00e850cd23ecf2e43
$ printf 'securitz' | shasum -a 256
fa18fd7fe735f03b5dcce3556a08491555cee1fe4b0a86c509aa693a4eb707dc
- One letter changed by one position. About half the output bits flipped
- This is required, not incidental: any visible relationship between
similar inputs would be a foothold
The Avalanche, Counted

The two digests from the previous slide, XORed. About half the bits flip,
and which half looks random — there is no
gradient for an attacker to follow back to the input.
A Collision You Can Download
$ shasum -a 1 s1.pdf s2.pdf
38762cf7f55934b34d179ae6a4c80cadccbb7f0a s1.pdf
38762cf7f55934b34d179ae6a4c80cadccbb7f0a s2.pdf
$ shasum -a 256 s1.pdf s2.pdf
2bb787a73e37352f92383abe7e2902936d1059ad9f1ba6daaa9c1e58ee6970d0 s1.pdf
d4488775d29bdef7993367d541064dbdda50d383f89f0aa13a6ff2e0894ba5ff s2.pdf
$ cmp s1.pdf s2.pdf
s1.pdf s2.pdf differ: char 193, line 8
Two different PDFs, one SHA-1. Produced by CWI and Google in 2017
and published at shattered.io.
Which Hash?
| MD5 | Collisions since 2004, in seconds. Dead |
| SHA-1 | Collision demonstrated 2017, chosen-prefix 2020. Dead |
| SHA-256 / SHA-512 | The SHA-2 family. Fine, and everywhere |
| SHA-3 | Different construction, kept as insurance against a break in SHA-2 |
| BLAKE2 / BLAKE3 | Fast, modern, well regarded |
"Dead" still means dead where a
deliberate collision matters —
certificates, signatures, code updates. Flame, in the PKI section, was all
three.
From Hash to MAC
- Lecture 1 left this open: a bare hash protects against
accident, because anyone who rewrites the data rewrites the
digest
- Add a key. A Message Authentication Code
can only be produced — and checked — by someone holding it
- HMAC is the right construction, and the
nesting is not decoration
HMAC(K, m) = H( (K ⊕ opad) ‖ H( (K ⊕ ipad) ‖ m ) )
Naively hashing key ‖ message is broken against SHA-2 by
length extension: an attacker who never
learns the key can still append to your message and produce a valid tag.
Length Extension, Drawn

SHA-256 publishes its whole internal state as the digest, so anyone can
pick up where the server stopped. HMAC's outer hash is what stops this.
Encryption Alone Is Not Integrity
- A ciphertext you cannot read is still a ciphertext you can
change
- In CTR mode, flipping bit i of the ciphertext flips bit
i of the plaintext. Exactly, predictably
- So
pay 100 to alice becomes something else of your
choosing, without the key - The answer is authenticated encryption:
confidentiality and integrity from one primitive, with one key
- AES-GCM · ChaCha20-Poly1305 · AES-CCM
- If you must combine them by hand, it is
encrypt-then-MAC. The other orders have
published attacks
The Bit Flip, Drawn

A real AES-CTR run. The attacker never saw the key — knowing the plaintext
said 1 was enough to make it say 9. The next
slide is the fix.
AES-GCM, and One Flipped Bit
ct := gcm.Seal(nil, nonce, plaintext, nil)
out, err := gcm.Open(nil, nonce, ct, nil)
fmt.Printf("open as sent: %q err=%v\n", out, err)
ct[3] ^= 0x01 // flip a single bit of the ciphertext
out, err = gcm.Open(nil, nonce, ct, nil)
fmt.Printf("open one bit flipped: %q err=%v\n", out, err)
plaintext 16 bytes pay 100 to alice
ciphertext 32 bytes e7cced5c...45ca5a1a
the last 16 bytes are the authentication tag
open as sent: "pay 100 to alice" err=<nil>
open one bit flipped: "" err=cipher: message authentication failed
Read the Output Again
- 16 bytes in, 32 bytes out — the extra 16
are the authentication tag. Integrity costs space
- The tampered open returned "", not
garbage. It refused to produce a plaintext at all
- That is the contract worth insisting on:
no output before the tag verifies. An API that
hands you unverified plaintext is an API that will be misused
Every tool so far assumes both sides already share a key. How did they
get it?
The Problem Symmetric Crypto Cannot Solve
- To send you an encrypted message I need a shared key. To share a key
securely I need… an encrypted channel
- For centuries the answer was couriers and codebooks. It does not scale
to a web with billions of pairs of strangers
- 1976, Diffie and Hellman: what if
encryption and decryption used
different keys, and only one of them
had to be secret?
Two Keys, Two Directions
- Everyone has a public key (published) and
a private key (never shared)
- What you get depends on which key you use
| Encrypt with the public key | only the holder of the private key can read it →
confidentiality |
| Sign with the private key | anyone can verify who it came from →
authentication, non-repudiation |
Same mathematics, opposite direction, completely different service.
Confusing the two is the classic exam mistake.
Where the Hardness Comes From
| RSA | Factoring a large integer is hard. Encrypts, and signs |
| Diffie–Hellman | Discrete logarithms are hard. Agrees on a shared key — does not
encrypt |
| Elliptic curve | The same problems over a curve, where they are harder per bit |
- None is proven hard. They are unbroken after decades of public
effort, which is the strongest claim cryptography makes
- A large quantum computer would break all three. Post-quantum standards
(ML-KEM, ML-DSA) were published by NIST in 2024
Key Sizes Are Not Comparable
| Security level | Symmetric | RSA / DH | Elliptic curve |
| 112 bits | 3DES | 2048 | 224 |
| 128 bits | AES-128 | 3072 | 256 |
| 192 bits | AES-192 | 7680 | 384 |
| 256 bits | AES-256 | 15360 | 512 |
NIST SP 800-57. A 256-bit elliptic-curve key and a 3072-bit RSA key are
the same strength — which is why everything new
uses curves.
In the Wild: ROCA, 2017
- Infineon's RSA library — in smartcards, tokens and TPMs, FIPS 140-2
certified — generated primes with a
specific structure. The randomness was fine;
the algorithm was not (CVE-2017-15361)
- The structure shows in the public key, and it makes factoring cheap: a
2048-bit key in about 140 CPU-years, roughly $20,000–40,000 of cloud
time — where the table promises 2112 work
- Estonia blocked the certificates of about 760,000 national ID cards on 3
November 2017
- The key size was right. The key
generation
was wrong — "never the key length", from How Big Is Big Enough
Source:
Nemec et al., The Return of Coppersmith's Attack (ACM CCS 2017)
·
Government of Estonia, 2 November 2017
Nobody Encrypts Data With RSA
- Public-key operations are
thousands of times slower than AES, and
RSA cannot encrypt more than its key size anyway
- Hybrid encryption is what actually runs:
- Generate a random symmetric key for this message
- Encrypt the data with AES-GCM under that key — fast
- Encrypt the key with the recipient's public key — small
- TLS, PGP, Signal, encrypted disks: all the same shape. Public key to
move a key, symmetric key to move the data
Hybrid Encryption, Drawn

Two ciphertexts travel together. The slow public-key step only ever
touches a key; the fast symmetric step touches everything else.
Diffie–Hellman, Drawn

Two strangers agree on a key over a public channel. It does not say
who is on the other end. Eve only listens, and learns nothing;
Mallory in the middle could run it with each of them — so the exchange
must be signed, as the next slide says.
Forward Secrecy
- If the session key is encrypted to a long-lived public key, then whoever
recorded the traffic today can decrypt
all of it the day that private key leaks
- Instead, agree a fresh key per session with
ephemeral Diffie–Hellman, and use the
long-term key only to sign the exchange
- Now the private key proves identity but decrypts nothing. Yesterday's
recording stays unreadable
- This is why TLS 1.3 removed static-RSA key exchange entirely: it made
forward secrecy non-optional
Forward Secrecy, Drawn

The leak only hurts the past if the key ever encrypted anything.
Here it only signed — the next section. It
can still impersonate the server from now on, but it cannot read the past.
Digital Signatures
- Hash the message, then transform the hash with the private key
- Hashing first is not an optimization — it is what lets a fixed-size
operation sign a message of any length
- Anyone with the public key can verify. Nobody else can produce one
- Algorithms: RSA-PSS · ECDSA · Ed25519
A signature over a broken hash is a broken signature — which is precisely
why SHA-1 mattered.
Sign and Verify, Drawn

Only the top row needs a secret. The bottom row can be run by
anyone — which is exactly what a MAC cannot
offer.
Sign, Verify, Tamper
$ openssl genpkey -algorithm ed25519 -out priv.pem
$ openssl pkey -in priv.pem -pubout -out pub.pem
$ openssl pkeyutl -sign -inkey priv.pem -rawin -in msg.txt -out msg.sig
sig bytes: 64
$ openssl pkeyutl -verify -pubin -inkey pub.pem -rawin \
-in msg.txt -sigfile msg.sig
Signature Verified Successfully
$ openssl pkeyutl -verify -pubin -inkey pub.pem -rawin \
-in msg2.txt -sigfile msg.sig # one character added
Signature Verification Failure
64 bytes, for a message of any size.
In the Wild: Sony PS3, 2010
- The PlayStation 3 ran only code carrying Sony's
ECDSA signature — the top row of the
signing diagram, with Sony's private key
- ECDSA needs a fresh random nonce for every
signature. Sony's signer used
the same one
every time
- fail0verflow, at 27C3 in December 2010: from two signatures, solve for
the nonce, then for the private key. Anyone could now sign code as Sony
- The Ed25519 we just ran derives its nonce from the key and the message
(RFC 8032), so there is no random number to get wrong
Source:
fail0verflow, Console Hacking 2010 (27C3)
·
the talk's slides
·
RFC 8032
Sony's Nonce, Drawn

The same rule as CTR mode, in a different equation: a nonce used twice
cancels out, and what is left is the secret.
MAC or Signature?
| MAC | Signature |
| Keys | one, shared | a key pair |
| Who can verify | anyone who can also forge | everyone, and only the owner can sign |
| Non-repudiation | no | yes |
| Speed | very fast | much slower |
Both give integrity and origin. Only the signature settles an argument —
with a MAC, either party could have produced the tag, so neither can prove
the other did.
Whose Public Key Is It?
- Everything above assumed you have
the right public key
- If an attacker can hand you their public key while claiming to
be the bank, every signature verifies perfectly — for the wrong party
- Cryptography cannot answer this. It is a
trust question, and it needs an outside
answer
Public-key cryptography does not remove the need to distribute something
securely. It reduces it to distributing something
public.
Certificates
- A certificate is a signed statement:
"this public key belongs to this name"
- Signed by a Certificate Authority
- An X.509 certificate carries, at minimum:
- Subject — the name it is about
- The subject's public key
- Issuer, validity dates, allowed uses
- The CA's signature over all of it
- Your trust in a website is a chain: leaf → intermediate →
root, and the root is
preinstalled in your OS or browser
The Chain of Trust

Each signature is checked with the key one step to the left. If the server
forgets to send the intermediate, there is a gap: unless the client
fetches the missing certificate itself, it holds a leaf it cannot connect
to any root.
In the Wild: Flame, 2012
- Espionage malware, announced in May 2012 by Kaspersky, CrySyS and Iran's
national CERT. It spread by posing as a
Windows Update
- Its code carried a valid signature chaining to Microsoft's root. A
Microsoft licensing CA was
still signing with MD5, though Microsoft
had banned MD5 for public CAs in 2009
- The attackers built a
chosen-prefix collision: the CA signed
one certificate, and the signature fitted another. CWI found it was a
variant nobody had published
- Microsoft revoked the CAs in June 2012. The real fix was the "Dead" row
of Which Hash?, applied everywhere
Source:
CWI, new cryptographic attack variant in Flame
·
Microsoft Security Advisory 2718704
Flame's Collision, Drawn

A signature is over the digest. Find two documents with one
digest and every signature on one is a signature on the other — the
collision column of the properties diagram.
The Chain Has Consequences
- Your browser trusts a few hundred roots. Any one of them can issue a
certificate for any name
- DigiNotar, 2011 — a compromised CA issued
a valid certificate for
*.google.com, used to intercept
Iranian users. The CA was distrusted and went bankrupt - The patches are structural, not cryptographic:
- Certificate Transparency — every
issued certificate is logged publicly, so misissuance is visible
- CAA records — the domain owner names
which CAs may issue for it
In the Wild: Symantec, 2015–2018
- September 2015: Google saw, in the
Certificate Transparency logs, an EV
pre-certificate for
google.com from Symantec's Thawte CA —
which Google had never asked for - It came from Symantec's internal testing. Its re-audit found 164 more
certificates over 76 domains, and 2,458 for domains never registered
- 2017: a partner in Korea had misissued under Symantec's name — 127
confirmed. Browsers judged the CA, not the certificate
- Chrome 70, October 2018,
stopped trusting everything Symantec's
old CA had issued; Firefox 64 in December. DigiNotar's fate, without a
breach
Who watches the CA? A public log that anyone can read.
Source:
Google, Improved Digital Certificate Security
·
Sustaining Digital Certificate Security
·
Mozilla, CA/Symantec Issues
·
Chrome's plan to distrust Symantec
Revocation Is the Hard Part
- A private key leaks on Tuesday. The certificate is valid until next year
- CRL — a list of revoked serial numbers.
Large, and stale between fetches
- OCSP — ask the CA about one certificate.
Adds a round trip, leaks your browsing to the CA, and clients
fail open when it times out
- A check that is skipped whenever it fails is not a check
- The direction that actually worked:
short-lived certificates. Ninety days,
then forty-seven — expiry does the job revocation could not
Keys Have a Life Cycle
- Generate — from a real CSPRNG.
Weak randomness has broken more keys than cryptanalysis
- Store — in an HSM, a KMS or the platform keystore. Not in the
repository, not in an environment variable if you can help it
- Distribute — the problem certificates exist to solve
- Rotate — on a schedule, so that rotating is a rehearsed operation and
not an emergency
- Destroy — and remember the backups, the snapshots and the old images
One key, one purpose. A key that both signs and encrypts turns any flaw in
either into a flaw in both.
In the Wild: Debian OpenSSL, 2008
- 2006: to silence a Valgrind warning, a Debian-only change to OpenSSL
removed the entropy from its random generator. Only the
process ID was left
- For twenty months every key OpenSSL made on Debian and Ubuntu came from
one of
32,767 seeds per architecture — a list
anyone could generate in advance (CVE-2008-0166)
- SSH, OpenVPN, DNSSEC and TLS keys all had to be regenerated. Even a good
DSA key that had merely signed on such a machine was lost — its
nonces were guessable, as on the Sony slide
- Generate failed silently;
Rotate became everyone's emergency at once
A grade server keyed on such a machine would have had its key on that
list.
Source:
Debian Security Advisory DSA-1571-1
·
Debian Wiki, SSLkeys
·
USN-612-1
The Grade Service, With This Toolbox
Lecture 1's threats, and which tool answers each one:
| A reader on the lab wifi | Authenticated encryption — inside TLS, lecture 6 |
| 12 changed to 20 on the wire | The same tag: a flipped bit fails to open |
| "I never entered that grade" | A signature by the instructor. A MAC cannot settle it |
| Is this really the grade server? | A certificate, checked up to a root |
| A student sends X-User: parham | Nothing in this lecture |
The last row is not a cryptography problem. The request is perfectly
intact — it is just a lie.
Rules That Will Serve You
- Do not implement it. Use a reviewed
library, at the highest level it offers
- Authenticated encryption by default —
AES-GCM or ChaCha20-Poly1305
- Never reuse a nonce under one key
- Randomness from the OS —
crypto/rand, not math/rand - Compare secrets in constant time — an
early-exit comparison leaks the answer through timing
- Keep the key and the data apart, and know where each one lives
The cipher is almost never what fails. The way it was used is.
Check Yourself
- The ECB picture was encrypted with AES, a strong cipher. Why could you
still read it?
- The grade upload is AES-CTR with no tag. Without the key, what can a
student on the wire do to their grade?
- Why does a MAC not give non-repudiation, when a signature does?
- The server's private key leaks next year. Which recordings of today's
traffic can be read — with static RSA, and with ephemeral
Diffie–Hellman?
Where This Leaves Us
- We can now keep a secret, notice a change, and prove who signed — and
every one of those reduces to who holds a key
- The grade service's last row still stands: a header that says
X-User: parham. No cipher fixes that - A key proves possession. It does not say what its holder is
allowed to do
Next: access control. Who you are, how you prove it, and what that lets
you touch.