Cryptography

Chapter 2
Cryptography Building Blocks
Symmetric & asymmetric encryption, hashing, and MACs — the primitives TLS combines

TLS doesn't invent its own cryptography — it assembles a handful of well-studied primitives into a protocol. This chapter introduces those primitives in plain terms, mapping each to the guarantee it provides (Chapter 1). You don't need the maths; you need to know what each tool does, what key it uses, and what it can't do alone.

Symmetric Encryption — One Shared Key

Symmetric encryption uses a single secret key to both encrypt and decrypt. The same key locks and unlocks — like a physical door key that both parties hold a copy of. The dominant algorithm is AES (Advanced Encryption Standard).

# the same key both scrambles and unscrambles plaintext --[ encrypt with KEY ]--> ciphertext ciphertext --[ decrypt with KEY ]--> plaintext

Symmetric encryption is fast — easily fast enough to encrypt every byte of a web page or video stream — and it delivers confidentiality. Its one hard problem: both sides must already share the same secret key. How do two strangers on the internet agree on a shared secret without an eavesdropper learning it? They can't, with symmetric crypto alone. That gap is exactly what asymmetric crypto solves.

Asymmetric Encryption — A Key Pair

Asymmetric (or public-key) encryption uses a pair of mathematically linked keys: a public key that can be shared with anyone, and a private key kept secret by its owner. What one key locks, only the other can unlock. The common algorithms are RSA and the elliptic-curve family (ECDH/ECDSA).

Use the…To…Giving you
recipient's PUBLIC key to encryptsend a secret only the holder of the matching private key can readConfidentiality (anyone can encrypt to you)
your own PRIVATE key to signprove a message came from you (only you have that key)Authentication (a digital signature)

This neatly solves the "strangers sharing a secret" problem: you can hand your public key to the whole world, and anyone can use it to send you something only your private key can open. The catch is that asymmetric operations are slow and computationally heavy — far too slow to encrypt an entire data stream.

The hybrid insight that makes TLS work
Symmetric is fast but needs a pre-shared key; asymmetric solves key sharing but is slow. TLS combines them: it uses asymmetric crypto briefly, during the handshake, only to agree on a fresh symmetric key — then switches to fast symmetric encryption (AES) for all the actual data. Slow-but-clever to set up, fast-and-simple to run. This hybrid model is the single most important idea in the whole course; Chapters 3 and 6 build directly on it.

Hashing — A One-Way Fingerprint

A cryptographic hash function (e.g. SHA-256) takes any input and produces a fixed-size "fingerprint" — the digest. It has three defining properties:

  • Deterministic: the same input always yields the same digest.
  • One-way: you cannot reverse a digest back into the original input.
  • Collision-resistant & avalanche: two different inputs (practically) never share a digest, and changing a single bit of input scrambles the entire output.
echo "hello" | sha256sum 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 # change ONE character -> a completely different digest (avalanche) echo "hellp" | sha256sum b40711a88c7039756fb8a73827eabe2c0fe5a0346ca7e0a104adc0fc764f528d

Hashing on its own provides integrity checking: if you know the expected digest of some data, you can re-hash what you received and confirm it wasn't altered. But note what hashing alone does not give you — see the next section.

A plain hash doesn't prove WHO sent the data
A hash detects accidental or malicious changes — but an attacker who modifies the data can simply recompute the hash to match their tampered version, since hash functions are public and keyless. So a bare hash protects integrity only if the digest itself arrives through some trusted, untampered channel. To bind integrity to a sender, you need a key in the mix — that's a MAC.

MACs — Integrity WITH a Key

A MAC (Message Authentication Code) is like a hash, but it also folds in a secret key. Only someone holding the key can produce a valid MAC for a message, and only someone with the key can verify it. The common construction is HMAC (e.g. HMAC-SHA256).

# sender, holding KEY: tag = HMAC(KEY, message) # send message + tag # receiver, also holding KEY: recompute HMAC(KEY, message) and compare to tag match -> message is intact AND came from a key-holder mismatch -> tampered, or forged by a non-key-holder -> reject

Because forging a valid tag requires the secret key, a MAC delivers integrity and a form of authentication at once: it proves the message wasn't altered and that it came from someone who shares the key. This is how TLS protects each record of application data after the handshake — using the symmetric key it just negotiated.

Modern TLS uses AEAD — encryption and integrity in one step
Rather than encrypt and then separately MAC, modern TLS (1.2's GCM suites and all of 1.3) uses AEAD ciphers — Authenticated Encryption with Associated Data, such as AES-GCM and ChaCha20-Poly1305. A single AEAD operation provides confidentiality and integrity together, producing both ciphertext and an authentication tag. You'll see names like TLS_AES_256_GCM_SHA384 in Chapter 8 — the "GCM" part is the AEAD mode. Conceptually it's still "symmetric encryption + a MAC," just fused into one safer primitive.

Putting the Primitives Against the Guarantees

PrimitiveKey modelSpeedProvides
Symmetric (AES)one shared secret keyfastConfidentiality
Asymmetric (RSA, ECDH)public + private key pairslowKey exchange & Authentication
Hash (SHA-256)no keyfastIntegrity (keyless)
MAC / HMACone shared secret keyfastIntegrity + sender authenticity
AEAD (AES-GCM)one shared secret keyfastConfidentiality + Integrity together

No single primitive provides all three guarantees — TLS is essentially the recipe for combining them: asymmetric crypto to establish a shared symmetric key and to authenticate the server (via certificates, Chapter 4), then AEAD symmetric crypto to protect every byte of data with confidentiality and integrity. The next chapter zooms in on the asymmetric half: how two parties actually agree on that shared key.

Hands-On Exercises

Exercise 1

Use sha256sum (or openssl dgst -sha256) to hash a short string, then hash it again after changing a single character. Confirm the digest length is identical but the value is completely different (the avalanche effect), and explain why this property matters for integrity checking.

📄 View solution
Exercise 2

Using openssl, time a symmetric operation vs an asymmetric one to feel the speed gap: generate an RSA key and do a public-key operation, and separately encrypt a chunk of data with AES. Then explain in your own words why TLS uses the slow asymmetric step only to set up the fast symmetric one.

📄 View solution
Exercise 3

For each item, name the primitive that fits and the guarantee it provides: (a) encrypting a 4 GB video stream efficiently; (b) letting strangers send you a secret with nothing pre-shared; (c) proving a downloaded file wasn't corrupted, given a trusted digest; (d) proving a message both is intact and came from someone sharing your key.

📄 View solution

Chapter 2 Quick Reference

  • Symmetric (AES) — one shared key encrypts & decrypts; fast; gives confidentiality; problem = sharing the key
  • Asymmetric (RSA, ECDH) — public + private key pair; slow; solves key sharing & enables signatures/authentication
  • Hybrid model — asymmetric to agree a fresh symmetric key, then symmetric for the bulk data (the core TLS idea)
  • Hash (SHA-256) — keyless one-way fingerprint; deterministic, irreversible, avalanche; gives keyless integrity
  • A plain hash can't prove who sent data — an attacker recomputes it; you need a key
  • MAC / HMAC — hash + secret key; integrity AND sender authenticity
  • AEAD (AES-GCM, ChaCha20-Poly1305) — fuses encryption + integrity in one step; used by modern TLS
  • Next chapter: public-key crypto & key exchange — RSA vs Diffie–Hellman, and forward secrecy