Chapter 17 — Cryptography concepts
Lesson map
Lesson 17 published. Map, example, EX049.
flowchart TD
N0["Learning outcomes"]
N1["17.1 Three tools"]
N2["17.2 The payment callback"]
N3["Lab — Lab — verifying a webhook"]
N4["17.3 Lab result"]
N5["17.4 Key management"]
N6["17.5 Do not invent crypto"]
N7["17.6 Replay"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX049"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["17.1 Three tools"]
N2["17.2 The payment callback"]
N3["Lab — Lab — verifying a webhook"]
N4["17.3 Lab result"]
N5["17.4 Key management"]
N6["17.5 Do not invent crypto"]
N7["17.6 Replay"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX049"]
[Learning outcomes]
|
v
[17.1 Three tools]
|
v
[17.2 The payment callback]
|
v
[Lab — Lab — verifying a webhook]
|
v
[17.3 Lab result]
|
v
[17.4 Key management]
|
v
[17.5 Do not invent crypto]
|
v
[17.6 Replay]
|
v
[Worked example] --> [Exercise EX049]
Learning outcomes
You will (1) distinguish hashing, message authentication and encryption; (2) verify message integrity with HMAC; (3) compare secrets safely; (4) manage keys.
17.1 Three tools
A hash such as SHA-256 creates a fingerprint of data; anyone can compute it. A message authentication code (MAC) such as HMAC-SHA256 uses a shared secret, so only holders of the secret can create a valid tag. Encryption hides content. Integrity and secrecy are different goals.
Lena uses each for its purpose: hashes for package integrity, MACs for messages from the payment provider and encryption for data at rest and in transit. Confusing them causes real mistakes: a hash alone cannot prove who sent a message, because anyone can compute it.
17.2 The payment callback
Chapter 2 found that CampusEats did not verify the payment provider's "paid" messages. Without verification, anyone who could send a request to the callback address could mark an order as paid. The provider signs each message with HMAC-SHA256 using a shared secret; CampusEats must check it.
Lena's diagram trace in chapter 2 flagged this as an unchecked message crossing a trust boundary. The fix is small in code but closes a direct path to free food. Lena writes the check before any other payment change, since every order depends on it.
Lab — Lab — verifying a webhook
"""Verify a payment webhook's HMAC-SHA256 signature (synthetic shared secret)."""
import hmac, hashlib
secret = b"synthetic-shared-secret"
body = b'{"order":"CE-1042","status":"paid","amount":"8.50"}'
good_sig = hmac.new(secret, body, hashlib.sha256).hexdigest()
altered = body.replace(b"8.50", b"0.50")
for name, b in (("original", body), ("altered amount", altered)):
ok = hmac.compare_digest(hmac.new(secret, b, hashlib.sha256).hexdigest(), good_sig)
print(f"{name:15} {'accept' if ok else 'reject: signature mismatch'}")
Run with python3 lab_hmac.py. Verified output:
original accept
altered amount reject: signature mismatch
17.3 Lab result
The original message is accepted because its signature matches. When the amount is changed from 8.50 to 0.50, the signature no longer matches and the message is rejected. The lab uses hmac.compare_digest, which compares in constant time and avoids leaking information through timing.
Lena adds tests for an unsigned message and a message with a signature from the wrong secret; both are rejected, and each rejection is logged with the time and source address. The lab also explains why constant time matters.
17.4 Key management
The shared secret is stored in the secret store, separate for test and production, and rotated when people with access leave.
Only the payment module reads it at runtime. If the secret were exposed, rotating it in the provider's dashboard and the store together would be the first step, and Lena writes that procedure into the runbook so nobody has to work it out under pressure. A rotation is tested each term, so the procedure is known to work. The procedure is short.
17.5 Do not invent crypto
Use standard algorithms and well-maintained libraries; home-made schemes fail in subtle ways. OWASP Top 10:2021 A02 covers cryptographic failures.
The payment callback check uses the standard library's HMAC functions rather than a custom comparison. When the society considered encrypting dietary preferences, Lena recommended the database's built-in encryption over a home-made scheme a member had written. The safe choice is usually the boring one, and its weaknesses, if any, are found and fixed by others. Lena adds this to the review checklist so that any new cryptographic code is flagged early.
17.6 Replay
A valid message could be sent twice. The provider includes a unique event ID; CampusEats stores processed IDs and ignores repeats.
Replay matters because a valid signature proves only that the provider sent the message at some point, not that it is new. Lena tests by sending the same signed message twice; the second is ignored and logged. Stored IDs are kept long enough to cover the provider's retry period, after which they can be removed safely. Lena records the retention period.
Worked example
After adding verification, Lena runs the test suite with synthetic callbacks: valid ones mark orders paid; altered and unsigned ones are rejected and logged. In the first month in production, three unsigned requests to the callback address are logged and rejected; they came from an automated scanner on the internet.
Synthetic case. Secrets and messages are synthetic.
Errors and limits
HMAC proves the sender knows the secret; if the secret leaks, forged messages pass.
Exercises
- EX049 — Hash vs HMAC. How does HMAC differ from a plain hash? Rubric: 3 = uses a shared secret; only holders can create tags; 2 = partial; 1 = vague; 0 = none.
- EX050 — Lab outcome. What happened when the amount changed? Rubric: 3 = signature mismatch; rejected; 2 = partial; 1 = vague; 0 = none.
- EX051 — Replay defence. How are repeated messages handled? Rubric: 3 = store event IDs; ignore repeats; 2 = partial; 1 = vague; 0 = none.
Synthesis
Use the right cryptographic tool for the goal and verify every signed message.
Continue studying — chapter 17 of 40
← Chapter 16 (draft) · Course chapter index · Chapter 18 (draft) →