Back to All Tutorials
AI & TechBeginner

Cryptography, Worked by Hand

From Caesar ciphers to TLS 1.3 — every concept built up with numbers you can follow step by step

Dr. Sam Mokhtari
~40m

Cryptography, Worked by Hand

A worked walkthrough of classical and modern cryptographic primitives — from Caesar ciphers to TLS 1.3 — with formal definitions, worked numerical examples, and the security proofs and attacks that matter in practice.

Dr Sam Mokhtari

Cryptography walkthrough overview

Cryptography is already in your pocket

Every network interaction you perform invokes at least one cryptographic primitive. Understanding which primitive does what job — and what happens when a primitive is misused — is the central practical skill of this walkthrough.

Opening a website

A TLS 1.3 handshake runs before the first HTTP byte is exchanged. Your credentials travel as AES-GCM ciphertext; an authentication tag on every record ensures the server is who the certificate claims, and that no byte was altered in transit.

Sending a WhatsApp message

The Signal Protocol uses an X3DH (Extended Triple Diffie-Hellman) key agreement, then a Double Ratchet for forward secrecy. The service provider observes only ciphertext; the session keys exist only on the endpoint devices.

Tapping your bank card

EMV generates a transaction-specific application cryptogram via 3DES or AES, keyed to the card's ICC master key. A captured cryptogram cannot be replayed because the terminal nonce changes each transaction.

Unlocking your phone

Full-disk or file-based encryption (AES-256-XTS on modern devices) wraps the volume key under a key derived from your PIN via a key-derivation function. The raw key never leaves the secure enclave; without the PIN, the wrapped key is computationally useless.

NOTE

Cryptography provides the formal mechanisms for confidentiality, integrity, authentication and non-repudiation. It does not address availability, physical security, or the correctness of the application logic that calls it.

For each of the four scenarios above, identify which of the four cryptographic goals (confidentiality, integrity, authentication, non-repudiation) is satisfied, and which is not. Justify each answer with reference to the specific primitive in use.

Four jobs cryptography does for us

Security goals precede algorithm selection. Choosing the wrong primitive — for example, applying a hash where authenticated encryption is required — is a design flaw regardless of how strong the primitive itself is. Each goal corresponds to a precise security property.

JobThe plain questionToolEveryday example
ConfidentialityCan only the right person read it?Encryption (AES, RSA)Your password travelling to your bank
IntegrityWas it changed on the way?Hash, MAC (SHA-256, HMAC)A downloaded file matching its checksum
AuthenticationIs it really from who it claims?MAC, certificatesThe padlock proving you reached the real bank site
Non-repudiationCan the sender deny it later?Digital signatureA signed e-contract or a signed software update
NOTE

Cryptography addresses Confidentiality and Integrity from the CIA triad directly, and enables Authentication through digital certificates and MACs. It provides no Availability guarantee: AES-GCM does not defend against a volumetric DDoS attack that exhausts server resources.

For a healthcare records system, map each of the four goals to a concrete data element or operation: which goal protects the record content, which ensures the record has not been modified after filing, which proves a prescription was issued by a licensed clinician, and which prevents that clinician from later denying authorship?

The cast: Alice, Bob and Eve

Cryptographic protocols are analysed under a formal threat model. The standard actors — Alice, Bob and Eve — represent roles in that model, not persons. Eve is typically assumed to be an active adversary (Dolev-Yao model) who can intercept, replay, modify and inject messages, not merely eavesdrop.

  • Plaintext (P or M): the message in recoverable form.
  • Ciphertext (C): the output of encryption; computationally indistinguishable from random under a secure cipher.
  • Cipher / algorithm: the publicly known transformation. Per Kerckhoffs's principle, security must reside entirely in the key, never in the secrecy of the algorithm.
  • Key (K): the secret parameter controlling the transformation. The entire security assumption rests here.
  • Encryption / decryption: EK(P) = C; DK(C) = P.
  • Cryptanalysis: the discipline of recovering P or K without legitimate access to K — the adversary's goal.
NOTE

Kerckhoffs's principle (1883): a cryptosystem should be secure even if everything about the system, except the key, is public knowledge. This is the foundation of modern cryptographic design and the reason algorithm secrecy ("security through obscurity") is not a valid security control.

Eve observes only ciphertext C. In a semantically secure (IND-CPA) scheme, C reveals no information about P beyond its length. Consider: why does revealing message length sometimes matter, and what real-world attacks exploit this? (Consider TLS-level attacks such as CRIME and BEAST.)

The Caesar cipher, by hand

The Caesar cipher is a monoalphabetic substitution cipher with a key space of 25. Encryption is defined as C = (P + k) mod 26, where P and C are letter indices in [0, 25]. Julius Caesar reportedly used k = 3. Despite its simplicity, the Caesar cipher illustrates two foundational concepts: Kerckhoffs's principle (the algorithm is public; only k is secret) and the necessity of an adequate key space.

1

Write the shifted alphabet (key k = 3)

A→D B→E C→F … X→A Y→B Z→C

2

Encrypt letter by letter

ATTACK AT DAWN becomes DWWDFN DW GDZQ

3

Decrypt by shifting back 3

Dk(C) = (C − k) mod 26. D→A, W→T, W→T… recovers ATTACK AT DAWN.

4

Exhaustive key search

The key space |K| = 25. Exhaustive search over all 25 shifts is O(25) — trivially automatable. A single known-plaintext letter immediately recovers k. This is not a brute-force concern: it is a total key-space inadequacy.

NOTE

The formal lesson: a cipher with a small key space provides no computational security regardless of the algorithm's structure. Key space must be large enough that exhaustive search is computationally infeasible given the adversary's resources. For modern standards this means at least 128 bits of entropy (2128 keys).

Verify: for k = 5, what is the ciphertext of the plaintext SECURE? What is the expected frequency of ciphertext letter 'J' in a long English message encrypted with k = 5, and how does this enable cryptanalysis without knowing k? (Hint: 'E' appears at frequency ≈ 12.7% in English.)

Three more old ciphers, and the trick that breaks them

Classical ciphers expose the two fundamental weaknesses that modern design must address: insufficient key space, and failure to destroy plaintext statistics. Shannon's criteria — confusion and diffusion — exist precisely to eliminate these weaknesses.

Substitution

A general monoalphabetic substitution maps each letter to a unique permutation of the alphabet. The key space is 26! ≈ 4 × 1026 — far beyond exhaustive search. Yet it is broken in practice by frequency analysis, because the substitution is letter-by-letter: high-frequency plaintext letters produce high-frequency ciphertext letters, and language statistics survive intact.

Frequency analysis

Al-Kindi formalised this in the 9th century: compare letter frequencies in the ciphertext against the known distribution of the target language. In English, E ≈ 12.7%, T ≈ 9.1%, A ≈ 8.2%. A quantitative sharpening is the index of coincidence (IC), the probability that two randomly chosen ciphertext letters are identical. English text has IC ≈ 0.065; random substitution produces IC ≈ 0.038. A high IC confirms a monoalphabetic (or short-key polyalphabetic) cipher, enabling targeted frequency matching rather than brute search.

Transposition (rail fence)

Transposition preserves plaintext letter frequencies entirely (IC is unchanged), defeating frequency analysis directly. However, known-plaintext or probable-plaintext attacks recover the transposition pattern readily. Combining substitution and transposition is the basis of product ciphers — and ultimately of AES.

Vigenère

A polyalphabetic substitution using a repeating keyword. ATTACKATDAWN with key LEMON becomes LXFOPVEFRNHR. The same plaintext letter encrypts differently at different positions, flattening single-letter frequencies. Kasiski (1863) and Friedman (1920) showed that the key length can be recovered from repeated ciphertext sequences, after which each Caesar sub-cipher is solved independently by frequency analysis. IC drops toward random (≈ 0.038) for long keys, providing a quantitative test for the key length.

NOTE

A large key space is necessary but not sufficient for security. A cipher must also eliminate statistical redundancy from the plaintext — Shannon called this diffusion. A cipher must also ensure that the relationship between key and ciphertext is complex — Shannon called this confusion. Classical ciphers fail on at least one of these criteria. AES is specifically designed to satisfy both.

Given a ciphertext with IC ≈ 0.065, what does this tell you about the cipher type? If the IC were ≈ 0.038, what would you conclude, and what would your next analysis step be to recover the key?

XOR and the one-time pad

XOR is the foundational bitwise operation in symmetric cryptography: a ⊕ b = 1 iff a ≠ b. Its key property is involution: (m ⊕ k) ⊕ k = m for any bits m, k. The one-time pad (OTP) applies XOR between the plaintext and a key drawn uniformly at random with |K| = |M|. Shannon proved in 1949 that the OTP achieves perfect secrecy: for all messages m and ciphertexts c, Pr[M = m | C = c] = Pr[M = m]. Equivalently, the ciphertext is statistically independent of the plaintext — the cipher is information-theoretically secure, providing security even against an adversary with unlimited computational power.

01 · Message to bits · H = 01001000

The ASCII encoding of 'H' as an 8-bit value; the OTP operates on bits directly.

02 · XOR with a uniformly random key · 01001000 ⊕ 10110101 = 11111101

The key must be drawn from a true random source (TRNG), not a PRNG, and must have the same length as the message.

03 · Send · Eve observes 11111101

By perfect secrecy, 11111101 is equally likely to be the encryption of any 8-bit character. Eve gains zero information about the plaintext from the ciphertext alone.

04 · Bob recovers the plaintext · 11111101 ⊕ 10110101 = 01001000 = H

XOR is its own inverse; applying the same key twice returns the original plaintext exactly.

NOTE

The VENONA project exposed the practical failure of the OTP: Soviet cryptographers in the 1940s reused key material under operational pressure. Key reuse destroys perfect secrecy: if C1 = M1 ⊕ K and C2 = M2 ⊕ K, then C1 ⊕ C2 = M1 ⊕ M2, eliminating the key entirely. US analysts exploited natural language redundancy in M1 ⊕ M2 to recover thousands of messages. The OTP's three requirements are therefore non-negotiable: key must be truly random, at least as long as the message, and used exactly once.

Compute 1100 ⊕ 1010, then XOR the result with 1010 again to verify involution. More importantly: if an attacker obtains two ciphertexts C1 and C2 produced with the same OTP key, explain in one paragraph why this completely breaks secrecy even without knowing K.

Two kinds of lock

All practical cryptosystems belong to one of two families, distinguished by the relationship between the encryption and decryption keys. Understanding the trade-offs between them is essential because real protocols — TLS, SSH, S/MIME — use both families together.

Symmetric-key cryptography uses a single secret key K shared between all authorised parties. EK(M) = C and DK(C) = M use the same key. The fundamental problem is secure key distribution: how do Alice and Bob establish K without it being intercepted? This is the key distribution problem that public-key cryptography solves.

Asymmetric (public-key) cryptography uses a mathematically linked key pair: a public key Kpub that is freely distributed, and a private key Kpriv that never leaves the owner's control. The security rests on a computational hardness assumption — for RSA, the integer factorisation problem (IFP); for Diffie-Hellman and elliptic-curve variants, the discrete logarithm problem (DLP). Computing Kpriv from Kpub must be computationally infeasible.

NOTE

Symmetric cryptography: n communicating parties require n(n−1)/2 pairwise shared keys. Asymmetric cryptography: each party requires exactly one key pair regardless of the number of correspondents. In practice, asymmetric operations are 100–1000× slower than symmetric ones, so hybrid encryption uses asymmetric cryptography once to establish a symmetric session key, then symmetric cryptography for bulk data.

Alice and Bob have never communicated before. Explain precisely why a symmetric cipher alone cannot establish confidential communication, and identify which component of a TLS 1.3 handshake resolves this — and which hardness assumption underpins it.

Stream ciphers vs block ciphers

Symmetric ciphers divide into two structural families. The distinction matters for mode of operation selection, performance characteristics, and failure modes under misuse.

  • Stream ciphers generate a pseudorandom keystream from a key (and typically a nonce), then XOR the keystream with the plaintext byte by byte — approximating an OTP with a short key. Security depends on the PRNG quality: the keystream must be computationally indistinguishable from a truly random sequence.
  • Suitable for low-latency applications (real-time audio, mobile) where block boundaries are inconvenient.
  • Current standard: ChaCha20 (Bernstein, 2008), used in TLS 1.3 as ChaCha20-Poly1305. RC4 is broken by statistical biases in its keystream and is prohibited in TLS (RFC 7465).
  • Block ciphers operate on fixed-size blocks; AES uses a 128-bit (16-byte) block size with key lengths of 128, 192 or 256 bits. Messages longer than one block require a mode of operation; the choice of mode determines whether patterns are hidden and whether integrity is provided.
  • A block cipher alone is a deterministic permutation: the same key + plaintext block always produces the same ciphertext block. This is precisely the ECB weakness.
  • Current standard: AES (FIPS 197, 2001). DES (56-bit key) and 3DES are retired; NIST deprecated 3DES in 2019 and disallowed it in 2024.
NOTE

Both families are secure when instantiated correctly. In practice, AES-GCM dominates server and desktop applications; ChaCha20-Poly1305 is preferred on constrained devices or where hardware AES acceleration is absent (since ChaCha20 is a software-friendly ARX construction).

A 100-byte message is encrypted with AES-CBC (PKCS#7 padding). How many 16-byte blocks are transmitted? (7: six full blocks of 96 bytes plus one padded block of 4 bytes + 12 bytes padding.) Why does AES-GCM not require this padding scheme?

From DES to AES: why key length matters

Key length determines the cost of exhaustive search: each additional bit doubles the adversary's work. This is not merely a linear improvement — the jump from 56-bit to 128-bit keys raises the brute-force cost by a factor of 272 ≈ 4.7 × 1021, far beyond the reach of any conceivable classical computer.

In 1998 the EFF's "Deep Crack" FPGA array recovered a 56-bit DES key in under 23 hours by testing approximately 90 billion keys per second — demonstrating that a |K| = 256 key space provides no practical security against a determined adversary with modest resources.

AES-128 has |K| = 2128 ≈ 3.4 × 1038. Even if every atom in the observable universe were a processor testing 1030 keys per second, exhaustive search would require time many orders of magnitude greater than the age of the universe. The best known attacks on AES reduce this by at most a few bits in contrived scenarios; AES remains unbroken in practice.

AES (originally Rijndael, designed by Joan Daemen and Vincent Rijmen) was selected by NIST as FIPS 197 in 2001 following a five-year public competition evaluating security, performance and implementation characteristics.

CipherKey sizeBlock sizeStatus today
DES56 bits64 bitsBroken. Never use.
3DES112 bits effective64 bitsRetired by NIST.
AES128 / 192 / 256 bits128 bitsThe standard everywhere.
NOTE

DES has 256 ≈ 7.2 × 1016 possible keys. At 109 guesses per second, exhaustive search takes approximately 2.3 years on average; Deep Crack achieved ≈ 90 × 109 guesses per second. 3DES (Triple-DES) applies DES three times with two or three independent keys, yielding 112 bits of effective security against meet-in-the-middle attacks — adequate in 1999 but deprecated by NIST in 2019 due to the Sweet32 birthday attack on its 64-bit block size.

Inside AES: four moves, repeated

AES is a Substitution-Permutation Network (SPN). The 128-bit block is arranged as a 4 × 4 byte state matrix and transformed over 10 rounds (128-bit key), 12 rounds (192-bit key), or 14 rounds (256-bit key). Each round applies four operations that together achieve Shannon's confusion and diffusion criteria, making AES resistant to both linear cryptanalysis and differential cryptanalysis.

1

SubBytes: non-linear substitution

Each byte is replaced by its image under the AES S-box, which is the multiplicative inverse in GF(28) followed by an affine transformation. The S-box is the primary source of confusion: it introduces non-linearity, breaking any linear relationship between plaintext, key, and ciphertext that linear cryptanalysis would exploit.

2

ShiftRows: inter-column dispersion

Row i of the state matrix is cyclically shifted left by i positions (i = 0, 1, 2, 3). This moves bytes into different columns, ensuring that bytes from a single column are spread across all four columns after MixColumns — a prerequisite for full diffusion.

3

MixColumns: linear diffusion

Each column of four bytes is multiplied by a fixed 4 × 4 MDS matrix over GF(28). The MDS (Maximum Distance Separable) property guarantees that any change in even one input byte affects all four output bytes — achieving Shannon's diffusion criterion. Combined with ShiftRows, MixColumns ensures the strict avalanche criterion: after a small number of rounds, a single changed input bit affects approximately half of all output bits.

4

AddRoundKey: key injection

The state is XORed with a 128-bit round key derived from the original key via the AES key schedule. Without this step, the cipher would be a public, invertible permutation affording no security. The key schedule introduces key-dependent non-linearity across rounds.

NOTE

The SPN structure is specifically engineered to defeat the two most powerful attacks on block ciphers. Differential cryptanalysis exploits predictable differences between plaintext pairs; the wide-trail design strategy ensures that any differential characteristic has probability at most 2−150 over 4 AES rounds. Linear cryptanalysis exploits linear approximations; the S-box's non-linearity bounds the advantage of any linear approximation. After 10 rounds, no attack on the full cipher significantly outperforms exhaustive key search.

Trace a single bit flip in byte (0,0) of the AES state through one full round (SubBytes → ShiftRows → MixColumns → AddRoundKey). How many state bytes are affected at the end of round 1? How many after round 2? This illustrates the Wide-Trail Strategy and why the diffusion bound is achieved within a small number of rounds.

A perfect cipher can still leak: ECB vs GCM

A block cipher is a keyed permutation on fixed-size blocks. Applied directly — without a mode of operation — it is Electronic Codebook (ECB) mode: each block is encrypted independently. ECB is deterministic: EK(Pi) = EK(Pj) whenever Pi = Pj. This means all structural patterns in the plaintext (repeated blocks, aligned boundaries) are preserved in the ciphertext. The "ECB penguin" demonstration — where encrypting a bitmap in ECB mode leaves the image's outline clearly visible — is a canonical illustration of this failure. ECB is not semantically secure (IND-CPA) because a ciphertext reveals equality of plaintext blocks.

  • ECB: each plaintext block Pi is encrypted independently as Ci = EK(Pi).
  • Identical plaintext blocks produce identical ciphertext blocks: plaintext structure leaks directly.
  • No ciphertext dependency between blocks: block reordering, deletion and insertion are undetectable.
  • Provides no integrity or authentication: ciphertext can be tampered with block-by-block without detection.
  • GCM (Galois/Counter Mode) is an Authenticated Encryption with Associated Data (AEAD) scheme. It combines CTR-mode stream encryption (providing confidentiality) with a GHASH polynomial authenticator over GF(2128) (providing integrity and authentication) in a single pass.
  • Requires a unique nonce per (key, message) pair: nonce reuse under GCM is catastrophic — it exposes the authentication key H = EK(0), breaking authentication on all past and future messages encrypted under that key. This is the nonce-misuse vulnerability.
  • Produces a ciphertext and a 128-bit authentication tag. Any modification to the ciphertext or associated data (e.g. headers) causes tag verification to fail, and decryption is rejected.
  • Mandated in TLS 1.3 as AES-128-GCM-SHA256 and AES-256-GCM-SHA384.
NOTE

When evaluating any system that "uses AES", the critical questions are: which mode, and is the nonce managed correctly? CBC (Cipher Block Chaining) hides ECB's pattern-leakage by XORing each plaintext block with the preceding ciphertext block before encryption, but provides no integrity protection — a separate MAC is required (Encrypt-then-MAC construction per RFC 7366). CBC with a padding oracle is vulnerable to the POODLE and Lucky13 attacks; these practical vulnerabilities drove the adoption of AEAD modes in TLS 1.3.

A database encrypts each customer's ISO country code independently using AES-128-ECB with a fixed key. Without knowing the key, what information can an attacker infer from the ciphertext database? How does this violate IND-CPA security? What mode should replace ECB, and what additional operational requirement does that mode impose?

The key distribution problem

Symmetric cryptography requires a pre-shared secret key between each communicating pair. For n parties communicating in all pairwise combinations, the number of distinct keys required is n(n − 1) / 2. This quadratic growth in key material — and the problem of establishing each key securely before communication begins — is the key distribution problem that motivated public-key cryptography.

The formula is n(n − 1) / 2 keys for n people.

PeopleKeys needed
510
1004,950
1,000499,500
NOTE

Before 1976, the only answer to key distribution was out-of-band pre-sharing: diplomatic couriers, physical key exchange, or dedicated secure channels. This was operationally feasible for military or government use with small teams, but it does not scale to open networks with millions of communicating parties. Diffie-Hellman key exchange (1976) solved this problem by enabling two parties to establish a shared secret over an entirely public channel, without any prior secret shared between them.

Five parties communicating in all pairs require 10 symmetric keys; a sixth party adds 5 more. For n = 100 parties: 4,950 keys; for n = 1,000: 499,500 keys. With asymmetric cryptography, each party requires exactly one key pair (2n key values total) regardless of n. Analyse the trade-off: if asymmetric operations are 1,000× slower than symmetric operations, at what point (in terms of n and message volume) does the overhead of asymmetric-only communication become prohibitive?

Agreeing a secret in public: the paint analogy

Diffie-Hellman key exchange (Diffie and Hellman, 1976) allows two parties to establish a shared secret over an insecure public channel without any prior shared secret. The security relies on the Computational Diffie-Hellman (CDH) assumption: given ga mod p and gb mod p, it is computationally infeasible to compute gab mod p without knowing a or b. This assumption is believed to hold when p is a large prime and g is a generator of a prime-order subgroup.

01 · Public parameters · Alice and Bob agree on a prime p and a generator g

These are published openly. Eve knows them. This is equivalent to agreeing on a "common colour" that mixing operations (modular exponentiation) will be applied to.

02 · Private exponents · Alice selects secret exponent a; Bob selects secret exponent b

These are never transmitted. Eve has no access to them.

03 · Public values · Alice transmits A = ga mod p; Bob transmits B = gb mod p

Eve observes A and B on the wire. Computing a from A (finding the discrete logarithm) is the DLP, which is computationally infeasible for appropriately chosen p.

04 · Shared secret · Alice computes Ba mod p = gab mod p; Bob computes Ab mod p = gab mod p

Both parties arrive at the same value gab mod p without it ever appearing on the wire.

05 · Eve's computational barrier · Eve holds p, g, A = ga mod p and B = gb mod p

To recover the shared secret she must solve the DLP (find a or b) or the CDH problem (compute gab from ga and gb). For a 2048-bit prime, no known polynomial-time classical algorithm can do this.

NOTE

DH as described provides no authentication: Eve can mount an active man-in-the-middle attack by intercepting A and B and substituting her own DH values on each side. Both Alice and Bob would establish shared secrets with Eve, not with each other. This is why Diffie-Hellman in practice must be combined with authentication — certificates in TLS, or pre-shared keys in IKE — to produce authenticated key exchange (AKE).

Diffie-Hellman with small numbers

The discrete logarithm problem (DLP): given a prime p, a generator g of Zp*, and a value A = ga mod p, find a. In Z23* this is trivially solvable by enumeration. In Zp* for a 2048-bit prime p, the best known algorithm (general number field sieve) requires sub-exponential but still astronomical time — this is the computational hardness on which DH security rests.

1

Public domain parameters

Prime p = 23, generator g = 5. These parameters are public; g = 5 generates all elements of Z23* (verify: 51, 52, … 522 mod 23 cover all values 1–22).

2

Alice's private exponent a = 6

She computes and sends A = 56 mod 23 = 15625 mod 23 = 8. (Verify: 15625 = 679 × 23 + 8.)

3

Bob's private exponent b = 15

He computes and sends B = 515 mod 23. Using repeated squaring: 515 mod 23 = 19.

4

Both compute the shared secret gab mod p

Alice: K = Ba mod p = 196 mod 23 = 2. Bob: K = Ab mod p = 815 mod 23 = 2. The shared secret K = 2 = 590 mod 23 = 56×15 mod 23, which neither transmitted.

5

Eve's DLP instance

Eve observes {23, 5, 8, 19}. To recover K she must solve 5a mod 23 = 8 (find a = 6) or 5b mod 23 = 19 (find b = 15). In Z23* this is trivial by enumeration. In a cryptographically sized group (|p| ≥ 2048 bits, or an elliptic-curve group of order ≥ 256 bits), no efficient algorithm is known — this is the CDH assumption.

NOTE

This toy example uses a 5-bit prime. Real-world DH uses either 2048-bit (RFC 3526) or 4096-bit finite-field groups, or elliptic-curve groups (ECDH) at 256 or 384 bits, which provide equivalent security with much smaller key sizes. TLS 1.3 mandates ECDHE (ephemeral ECDH) using curves such as X25519 or P-256, providing forward secrecy: compromise of the long-term server private key does not retroactively expose past session keys.

Using p = 23, g = 5, a = 4, b = 3: compute A, B and the shared secret K step by step. (A = 54 mod 23 = 4; B = 53 mod 23 = 10; K = 104 mod 23 = 43 mod 23 = 18.) Now explain why this example is completely insecure from an adversarial standpoint, and what group-theory property of p = 23 contributes to its weakness.

RSA with numbers you can do on paper

RSA (Rivest, Shamir, Adleman, 1977) derives its security from the Integer Factorisation Problem (IFP): given a composite modulus n = pq where p and q are large primes, factoring n to recover p and q is computationally infeasible with known algorithms when |n| ≥ 2048 bits. The private key is recoverable from the public key only if n can be factored. Note critically: textbook RSA as presented below is IND-CPA insecure — it is deterministic, so an adversary can distinguish encryptions of known plaintexts. In practice, RSA encryption requires OAEP (Optimal Asymmetric Encryption Padding, RFC 8017) to achieve IND-CCA2 security.

01 · Key generation · Choose primes p = 3, q = 11; compute n = pq = 33

In production RSA-2048, p and q are randomly chosen 1024-bit primes. n is the public modulus; p and q must be securely destroyed or never stored after key generation.

02 · Euler's totient · φ(n) = (p − 1)(q − 1) = 2 × 10 = 20

φ(n) is the order of the multiplicative group Zn*. Only the owner can compute this because it requires knowing p and q separately; computing it from n alone is equivalent to factoring n.

03 · Public exponent · e = 3, chosen so gcd(e, φ(n)) = 1. Public key = (e, n) = (3, 33)

Common choices in practice are e = 65537 (216 + 1), chosen for efficient exponentiation and to avoid small-exponent attacks. The public key is freely distributed.

04 · Private exponent · Compute d = e−1 mod φ(n) via the Extended Euclidean Algorithm: d = 7 since 3 × 7 = 21 ≡ 1 mod 20. Private key = (d, n) = (7, 33)

The security of RSA requires that d cannot be computed from (e, n) without knowing φ(n), which requires factoring n.

05 · Encryption and decryption · C = me mod n = 43 mod 33 = 64 mod 33 = 31. Decryption: m = Cd mod n = 317 mod 33 = 4 ✓

Correctness follows from Euler's theorem: med ≡ m1 + kφ(n) ≡ m mod n for gcd(m, n) = 1. Anyone holding (e, n) can encrypt; only the holder of d can decrypt.

NOTE

This toy example uses n = 33, which any attacker can factor trivially. Practical RSA requires |n| ≥ 2048 bits (NIST recommendation through 2030) or ≥ 3072 bits (beyond 2030). More importantly: never use textbook RSA in practice. Without OAEP padding, textbook RSA is homomorphic (E(m1) × E(m2) = E(m1m2 mod n)), malleable, and IND-CPA insecure. Use RSA-OAEP for encryption (PKCS#1 v2.2) and RSA-PSS for signatures (PKCS#1 v2.1).

Symmetric vs asymmetric, and why we use both

Students often ask which family is better. Neither: each is good at a different job. So real systems use hybrid encryption: public-key crypto to agree a key, then fast symmetric crypto for the data.

FeatureSymmetric (AES)Asymmetric (RSA, ECC)
KeysOne shared secretPublic + private pair
SpeedVery fast, built into CPUsHundreds to thousands of times slower
Keys for 1,000 users499,5001,000 pairs
Typical key size128–256 bitsRSA 2048–3072 bits; ECC 256 bits
Best atEncrypting bulk dataSharing keys, digital signatures
NOTE

The practical design pattern is hybrid encryption: asymmetric cryptography (RSA-OAEP or ECDH) is used once to establish or encapsulate a symmetric session key; all bulk data is then encrypted with AES-GCM or ChaCha20-Poly1305. This combines the key-distribution advantage of asymmetric cryptography with the performance of symmetric cryptography. Every TLS session, PGP-encrypted email, and encrypted file archive uses this hybrid construction.

For a 2 GB video transmitted over TLS 1.3: which operations use ECDHE, which use AES-256-GCM, and approximately how many AES-GCM records are generated (given TLS 1.3's default 16 KB record limit)? Why would encrypting 2 GB directly with RSA-4096 be infeasible even ignoring security considerations?

Hashing: a fingerprint for data

A cryptographic hash function H: {0,1}* → {0,1}n maps an arbitrary-length input to a fixed-length digest. SHA-256 produces n = 256 bits. Three distinct resistance properties are required, and each is progressively stronger:

  • Pre-image resistance: given h, it is computationally infeasible to find any m such that H(m) = h. (One-wayness: the function is easy to compute but infeasible to invert.)
  • Second pre-image resistance: given m1, it is computationally infeasible to find m2 ≠ m1 such that H(m2) = H(m1). (A known document cannot be substituted for a different document with the same hash.)
  • Collision resistance: it is computationally infeasible to find any pair (m1, m2) with m1 ≠ m2 and H(m1) = H(m2). This is the strongest property — collision resistance implies second pre-image resistance but not vice versa. By the birthday paradox, a collision requires only O(2n/2) evaluations, which is why SHA-1 (n = 160) provides only 80-bit collision resistance.
  • Avalanche effect: a single-bit change to the input produces an output that differs in approximately half of all bits — ensuring that related inputs produce uncorrelated digests.

SHA-256 outputs for "hello" and "Hello" are entirely unrelated — a 1-bit difference in the input produces an apparently random change across all 256 output bits, illustrating both the avalanche effect and the infeasibility of working backwards from the digest.

NOTE

MD5 (128-bit) and SHA-1 (160-bit) are both broken for collision resistance. The SHAttered attack (2017) produced two distinct PDF files with identical SHA-1 digests using a chosen-prefix collision — a meaningful attack that enables document substitution. MD5 collisions can be computed in seconds on commodity hardware. These functions must not be used for integrity verification, digital signatures, or certificate fingerprints. Use SHA-256, SHA-384, SHA-512 (SHA-2 family) or SHA3-256 (Keccak-based, FIPS 202).

Run echo -n hello | shasum -a 256 on a Unix system and verify the output. Then: given that SHA-256 produces a 256-bit output, what is the expected number of hash evaluations to find a collision by birthday attack? How does this compare to finding a pre-image? Why does SHA-1's 160-bit output provide insufficient collision resistance for modern certificate chains?

Use a hash: verify a download

Hash-based integrity verification relies on second pre-image resistance: an attacker who has modified a file cannot (practically) produce a modified file that matches the original's SHA-256 digest. This is a common application of integrity checking in software distribution.

1

Obtain the publisher's reference digest

The publisher computes SHA-256 over the release binary and publishes the hex digest alongside the download link. The digest is the integrity commitment.

2

Compute the digest locally

Windows: certutil -hashfile file.iso SHA256 / macOS or Linux: shasum -a 256 file.iso. The hash is computed over the complete file; any modification — even one bit — produces a different digest.

3

Compare the digests

A mismatch of any character indicates either file corruption in transit or deliberate modification. The avalanche effect ensures no partial match is possible: a modified file will differ in approximately half its digest bits, not just in bits corresponding to modified bytes.

4

Security boundary: hashes alone do not authenticate the source

If an attacker controls the web page (as occurred in the 2016 Linux Mint supply-chain attack), they can replace both the download and the published hash simultaneously. Hash verification only detects corruption or modification relative to a trusted reference; it cannot establish that the reference itself is authentic. That requires a digital signature over the digest using a key whose authenticity is established by a PKI or web of trust.

NOTE

The 2016 Linux Mint incident: attackers compromised the distribution website and replaced the official ISO with a backdoored version, updating the published SHA-256 hash to match. Users who checked the hash against the compromised page were given false assurance. This illustrates the trust-chain requirement: the hash must be obtained from an independent, authenticated source (e.g. verified via GPG signature from the developer's known key). Hash verification alone is integrity checking, not authentication.

Hash a small text file, modify a single byte, and rehash. Quantify: of the 64 hex characters in the SHA-256 digest, approximately how many changed? Does the changed position correlate with the position of the modified byte? What does this tell you about SHA-256's diffusion properties?

Storing passwords: weak vs strong

Password storage is a common application of cryptographic hashing, but the naive approach — hashing passwords with a general-purpose cryptographic hash function — is insecure. Two distinct attacks must be mitigated with different countermeasures, and confusing them leads to incomplete defences.

  • Plaintext storage: immediate total exposure on any database breach. No cryptographic protection whatsoever.
  • Fast, unsalted hash (MD5, SHA-256): susceptible to precomputation attacks. An attacker builds a rainbow table — a time-memory trade-off structure precomputing H(p) for millions of common passwords p — and looks up cracked passwords in O(1) time per hash. Two users with the same password have identical hashes; cracking one cracks both.
  • Fast hash, even with salt: a per-user random salt defeats rainbow tables (precomputed tables cannot account for per-user salts), but leaves the hash vulnerable to online guessing. A modern GPU can evaluate SHA-256 at ~1010 iterations per second. At this rate, an attacker with access to the hash database can test all passwords from a 109-entry wordlist in seconds per hash.
  • LinkedIn breach (2012): approximately 117 million unsalted SHA-1 password hashes were exfiltrated. The majority were cracked within hours using precomputed tables, demonstrating the real-world cost of inadequate password hashing.
  • Per-user random salt: a cryptographically random value (≥ 128 bits) unique to each user, stored alongside the hash. The stored value is H(salt ‖ password). Salt neutralises precomputation by ensuring that H(salt1 ‖ p) ≠ H(salt2 ‖ p) even when p is identical, forcing the attacker to crack each hash independently.
  • Memory-hard password hash function: Argon2id (winner of the Password Hashing Competition, 2015), bcrypt, or scrypt. These functions are deliberately slow and memory-intensive, configured via cost parameters (time cost, memory cost, parallelism). A single verification might take 100ms and require 64 MB of memory — acceptable for a login but imposing 104× overhead on an attacker guessing 106 passwords per second. Argon2id is the current NIST SP 800-63B recommendation.
  • Multi-factor authentication: ensures a cracked password alone is insufficient for account compromise.
NOTE

Two users with password "Password1": without salt, H("Password1") is identical for both. Cracking one entry cracks both simultaneously. With per-user salts s1 and s2: Argon2id(s1, "Password1") and Argon2id(s2, "Password1") are computationally independent — each must be cracked separately at full memory-hard cost. The salt is not secret and is stored in the clear alongside the hash.

Explain precisely why salting defeats rainbow table attacks but does not defeat online guessing attacks. Then explain why a memory-hard function defeats online guessing but does not defeat a breach of the hash database if the attacker has parallel GPU resources — and what additional control (beyond Argon2id) addresses that residual risk.

Digital signatures: a wax seal only you own

A digital signature scheme consists of three algorithms: KeyGen (produces a signing key sk and verification key vk), Sign (produces a signature σ = Sign(sk, m)) and Verify (outputs accept or reject given vk, m, σ). The formal security goal is existential unforgeability under chosen-message attack (EUF-CMA): an adversary who can obtain valid signatures on arbitrarily chosen messages of their choice must still be unable to forge a valid signature on any message they have not previously queried. EUF-CMA captures the practical requirement that digital signatures provide non-repudiation even when the adversary is adaptive.

01 · Hash the message · Alice computes h = SHA-256(M)

Signing the hash (a fixed-length digest) rather than the message directly makes the scheme efficient and independent of message length. The hash must be collision-resistant: if an attacker can produce m ≠ m' with H(m) = H(m'), a signature on m is also a valid signature on m'.

02 · Sign · Alice computes σ = hd mod n using her RSA private key (d, n)

Only Alice possesses d. For production use, this uses RSA-PSS (Probabilistic Signature Scheme) which adds randomisation to achieve EUF-CMA security. Textbook RSA signing is deterministic and lacks provable security in the standard model.

03 · Verify · Bob computes σe mod n using Alice's public key (e, n) and checks it equals h = SHA-256(M)

If the values match, the signature is valid: only the holder of d could have produced σ, and M has not been modified since signing.

04 · Security properties delivered · A valid signature implies: integrity (M is unmodified), authentication (Alice's key produced σ), and non-repudiation (Alice cannot deny signing without denying ownership of her private key)

All three properties are established simultaneously and inseparably by a single valid signature verification.

NOTE

An HMAC (Hash-based Message Authentication Code) uses a shared symmetric key K: MAC = HMAC(K, M). Either party holding K can compute a valid MAC, so HMACs provide integrity and authentication between parties who share K, but cannot provide non-repudiation — either party could have generated the tag. Digital signatures, by contrast, use an asymmetric key pair: only the private-key holder can sign, so any verifier with the public key can attribute the signature to a unique signer. In practice, ECDSA (FIPS 186-5) or Ed25519 (RFC 8032) are preferred over RSA for new deployments due to shorter signatures and faster operations.

Using the toy RSA keys n = 33, e = 3, d = 7: compute σ = Sign(d, h) for h = 5 (i.e. σ = 57 mod 33). Verify: Verify(e, h, σ) = σ3 mod 33. (Answer: σ = 14; verification: 143 mod 33 = 2744 mod 33 = 5 ✓.) Now explain why an EUF-CMA adversary presented with this toy system could forge a signature on an arbitrary hash value without querying the private key.

Certificates and PKI: an ID card for a public key

A raw public key provides no identity binding — an adversary can generate a key pair and claim any identity. X.509 certificates (RFC 5280) solve this by binding an identity (a Subject Alternative Name, e.g. bank.ae) to a public key, with the binding authenticated by a digital signature from a Certificate Authority (CA). The CA's signature chain terminates at a root CA whose certificate is pre-installed in the trust store of the client's operating system or browser — this is the Public Key Infrastructure (PKI) trust model.

A TLS client validates four properties before trusting a certificate:

  • Chain validity: the signature chain from the leaf certificate through any intermediate CAs to a trusted root must be cryptographically valid at each step. Each certificate in the chain is signed by the CA above it.
  • Name binding: the Subject Alternative Name (SAN) or Common Name (CN) field must match the domain name being accessed. A certificate for bank.ae does not authenticate payments.bank.ae unless the SAN includes a wildcard or explicit entry.
  • Temporal validity: the current time must fall within the notBefore and notAfter fields. Expired certificates indicate a key management failure.
  • Revocation status: the certificate must not appear on the CA's Certificate Revocation List (CRL) or have a negative response from the Online Certificate Status Protocol (OCSP). Certificate Transparency (CT) logs provide an additional public audit trail.
NOTE

The DigiNotar breach (2011) illustrates the systemic risk of the CA trust model. Attackers compromised the Dutch CA and issued fraudulent certificates for google.com, enabling man-in-the-middle attacks against approximately 300,000 users in Iran. Once a root CA is compromised, every certificate it has issued — or any intermediate CA it has signed — becomes untrustworthy. Browser vendors revoked all DigiNotar certificates within days; the company filed for bankruptcy within weeks. The incident accelerated the development of Certificate Transparency (RFC 6962) as a mandatory audit mechanism, and prompted HSTS preloading and certificate pinning as client-side mitigations.

Open any HTTPS site in a browser and inspect the full certificate chain. Identify: the leaf certificate's SAN, the issuing intermediate CA, the root CA in your trust store, and the certificate's OCSP responder URL. Consider: if the root CA's private key were compromised, which deployed mitigations (CT logs, HSTS, CAA DNS records) would and would not prevent an attacker from issuing a trusted certificate for that domain?

The TLS 1.3 handshake: everything at once

TLS 1.3 (RFC 8446, 2018) integrates every primitive covered in this walkthrough into a single protocol completing in one round trip (1-RTT). Compared to TLS 1.2, TLS 1.3 eliminates static RSA key exchange (which lacks forward secrecy), removes negotiation of weak algorithm combinations (RC4, CBC with SHA-1, export-grade ciphers), and mandates ECDHE — ensuring that compromise of a long-term server private key cannot retroactively expose past session traffic (forward secrecy).

01 · ClientHello · Client sends supported cipher suites, ECDHE key share, and client random

The key share is the client's ephemeral ECDHE public value (typically X25519 or P-256). TLS 1.3 specifies a small set of approved cipher suites: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256. All include AEAD and ECDHE — no negotiation of weaker options is possible.

02 · ServerHello · Server selects cipher suite, sends its ECDHE share, certificate and CertificateVerify signature

The CertificateVerify is a digital signature over the handshake transcript using the server's private key. It proves the server possesses the private key corresponding to the certificate's public key, preventing a passive observer from impersonating the server with a copied certificate.

03 · Certificate chain verification · Client validates the certificate chain, name binding, revocation status and CertificateVerify signature

This defeats the unauthenticated DH man-in-the-middle attack: Eve cannot produce a valid CertificateVerify for the server's certificate without possessing the server's private key. The combination of ECDHE + authenticated certificate is Authenticated Key Exchange (AKE).

04 · Key derivation · Both parties derive session keys from the ECDHE shared secret using HKDF (HMAC-based Key Derivation Function)

TLS 1.3 derives multiple keys from the master secret: separate keys for each direction, for application data, and for handshake records. The ECDHE shared secret itself is never used directly as a symmetric key; it is processed through HKDF with handshake transcript material, binding the keys to this specific session.

05 · Application data · All subsequent records are encrypted with the negotiated AEAD cipher (AES-128-GCM or ChaCha20-Poly1305)

Each TLS record carries an authentication tag; modification of any byte of the ciphertext or the record header causes tag verification failure and connection termination. This is hybrid encryption: ECDHE (asymmetric) established the key; AES-GCM (symmetric) encrypts the data.

NOTE

In Chrome DevTools (F12) → Security tab: inspect the protocol version, key exchange group (e.g. X25519), and cipher suite for any HTTPS connection. Identify each component: the ECDHE group (key exchange), the AEAD algorithm (encryption + integrity), and the HKDF hash (key derivation). Consider: why does TLS 1.3 encrypt the server certificate in the handshake, whereas TLS 1.2 sent it in cleartext?

End-to-end encryption: who can read your chat?

Transport encryption (TLS) protects data between a client and a server, but the server decrypts and re-encrypts at each hop. The service provider can read all messages. End-to-end encryption (E2EE) ensures that encryption keys are held exclusively by the communicating endpoints; the infrastructure provider handles only ciphertext that it cannot decrypt.

WhatsApp, Signal and iMessage use the Signal Protocol (Marlinspike et al.): X3DH (Extended Triple Diffie-Hellman) for initial key agreement using a combination of identity keys, signed pre-keys and one-time pre-keys, followed by a Double Ratchet algorithm that derives a fresh symmetric key for every message. The Double Ratchet provides both forward secrecy (compromise of the current state does not expose past messages) and break-in recovery (an adversary who compromises the current state cannot read future messages once the ratchet advances). This is a substantially stronger security model than session-based encryption.

NOTE

The distinction between transport and end-to-end encryption is architecturally significant. In transport-encrypted messaging, the provider holds plaintext: it can be read by insider threat, subpoenaed under legal process, or exfiltrated in a server breach. In E2EE, a subpoena of the server infrastructure yields only ciphertext; the provider is cryptographically incapable of producing plaintext. The security guarantee transfers from trusting the provider to trusting the correctness of the cryptographic protocol and the endpoint implementation.

Cloud backups of E2EE chats may be stored in plaintext or with provider-held keys unless explicitly configured otherwise — a common operational failure that negates the E2EE guarantee for archived messages.

In WhatsApp, the Safety Number (displayed as a QR code or 60-digit number) is a hash of the X3DH identity public keys of both parties. Comparing Safety Numbers out-of-band confirms that no MITM has substituted different identity keys — the same verification step that PGP's web of trust and Signal's safety number perform. If the codes match on both devices, the key agreement used genuine identity keys and the session is not intercepted.

Explain precisely why a provider that offers E2EE but stores backup copies of messages on their servers with provider-held keys does not provide meaningful E2EE. Which threat models does this fail against that a correctly implemented E2EE scheme would address?

Key management: where real systems fail

Cryptographic algorithm failures are rare in production systems. Key management failures — leaked credentials, hardcoded secrets, inadequate rotation, and improper storage — account for the vast majority of real-world cryptographic breaches. A key has a lifecycle, and each stage has security requirements that must be enforced operationally.

StageWhat happensGood practice
GenerateCreate the key materialUse a CSPRNG (Cryptographically Secure PRNG) seeded from a high-entropy source (OS entropy pool: /dev/urandom, CryptGenRandom). Key material must never be derived from predictable values (timestamps, PIDs, usernames). For asymmetric keys: use a HSM or secure enclave for generation to prevent export of raw key material.
StoreProtect the key at restHardware Security Module (HSM) for high-assurance storage; accessed via PKCS#11 API. Cloud KMS (AWS KMS, Azure Key Vault, GCP Cloud KMS) for managed key storage with audit logging. OS keychain (macOS Keychain, Windows DPAPI) for application-level secrets. Keys must never be stored in source code, version control, plaintext configuration files, or environment variables without an additional protection layer.
DistributeGet the key to authorised partiesVia authenticated key exchange (TLS + mutual authentication, ECDHE, KMS API with IAM policies). Never via email, chat, tickets or shared documents — these channels leave key material in persistent, uncontrolled logs.
RotateReplace the key periodicallyOn a defined schedule (e.g. annually for symmetric keys, aligned to NIST SP 800-57 recommendations) and immediately on any access-rights change (personnel departure, role change, suspected compromise). Automated rotation via cloud KMS eliminates the operational burden and human-error risk.
RevokeCancel the key before scheduled expiryImmediately on confirmed or suspected compromise. For certificates: CRL publication and OCSP responder update within hours. For symmetric keys: KMS key disablement propagates to all consuming services if the KMS API is the sole access path.
DestroyRender the key and its data permanently unrecoverableCryptographic erasure ("crypto-shredding"): deleting the key makes all data encrypted under it computationally unrecoverable without physically destroying the storage. NIST SP 800-88 guidelines for media sanitisation apply to physical key storage. For cloud-hosted data at scale, crypto-shredding is the only practical deletion mechanism.
NOTE

Toyota's T-Connect breach (2022): an access key granting read access to a cloud-hosted customer database was committed to a public GitHub repository and remained there for approximately five years. The underlying AES encryption of the database was correctly implemented. The failure was entirely in key management — specifically, storage (committed to version control) and distribution (published to an unauthenticated public endpoint). This pattern — correct cryptography, catastrophic key management — is the dominant failure mode in real system breaches. Secret scanning tools (GitHub Advanced Security, truffleHog, detect-secrets) exist specifically to detect and alert on committed credentials.

A team stores their database encryption key in a shared Google Sheet and rotates it by manually updating the application configuration during deployments. Identify every key lifecycle stage that is violated, the specific security property that each violation undermines, and the remediation for each — referencing specific tools or standards where appropriate.

How attackers go after cryptosystems

Attacks on deployed cryptosystems rarely target the underlying mathematical hardness assumption directly — breaking AES or the discrete logarithm problem with a classical computer is computationally infeasible. Instead, adversaries exploit protocol design flaws, implementation errors, key management failures, or auxiliary information channels. Understanding the attack surface beyond the algorithm is essential for fielding secure systems.

Brute force and exhaustive key search

An adversary enumerates all possible keys until decryption produces intelligible plaintext (or a known plaintext/ciphertext pair matches). Feasible only against small key spaces: Caesar (25 keys), DES (256). Defence: key length ≥ 128 bits for symmetric ciphers (AES-128 or AES-256); ≥ 2048 bits for RSA; ≥ 256 bits for elliptic-curve schemes. Key length requirements scale with the assumed adversary's computational resources and the required security horizon.

Man-in-the-middle (MITM)

An active adversary intercepts the key exchange and establishes independent session keys with each party, proxying messages between them. Both Alice and Bob believe they are communicating directly when in fact every message passes through Eve in plaintext. Unauthenticated Diffie-Hellman is inherently vulnerable to MITM because it provides no identity binding. Defence: authenticated key exchange using certificates (PKI) or pre-shared keys. TLS prevents MITM via the CertificateVerify signature; ECDHE without a certificate does not.

Replay attacks

An adversary captures a valid, authenticated message and retransmits it later to achieve an unintended effect. The captured message is cryptographically valid (the MAC or signature verifies correctly), so purely cryptographic checks cannot detect the replay. Defence: include a challenge-response nonce, a monotonically increasing sequence number, or a short-lived timestamp in the authenticated data, ensuring that valid messages are unique and expire. TLS session tickets, TLS sequence numbers, and FIDO authentication challenges all implement this pattern.

Side-channel attacks

An adversary measures physical or computational by-products of the cryptographic computation — execution time, power consumption, electromagnetic emissions, or acoustic signals — to extract information about the key without breaking the algorithm directly. Timing attacks (Kocher, 1996) against naive RSA implementations recover private key bits by measuring decryption time. Power analysis (SPA/DPA) extracts AES round keys from embedded devices. Heartbleed (CVE-2014-0160) was a memory safety vulnerability in OpenSSL's heartbeat extension that allowed an attacker to read 64 KB of server heap memory per request — potentially including private key material, session keys, and passwords. The TLS/AES implementation was correct; the surrounding C code was not. CRIME (2012) and BEAST (2011) exploited TLS-level compression and CBC predictability respectively to recover encrypted data byte by byte — attacking the protocol's structure rather than the cipher's key. Defence: constant-time algorithm implementations; hardware security modules (HSMs) that isolate key material from the CPU; compiler flags and OS mitigations (ASLR, stack canaries); TLS configurations that disable compression and CBC where AEAD alternatives exist.

NOTE

Post-quantum cryptography: Shor's algorithm running on a cryptographically relevant quantum computer would solve the integer factorisation problem (breaking RSA) and the discrete logarithm problem (breaking DH and ECDH) in polynomial time. AES-256 is believed to retain approximately 128 bits of security against Grover's algorithm on a quantum computer (which provides a quadratic speedup for search, not exponential). NIST finalised the first post-quantum cryptography standards in 2024: ML-KEM (Module Lattice Key Encapsulation, FIPS 203) for key exchange and ML-DSA (Module Lattice Digital Signature, FIPS 204) for signatures, both based on the hardness of the Module Learning With Errors (MLWE) problem. Organisations handling data with long secrecy requirements should begin cryptographic agility planning now to accommodate migration to post-quantum algorithms.

A contactless building-access card transmits a fixed 32-bit value on each tap. Identify which attack class this enables, explain the exact mechanism by which access can be obtained without a legitimate card, and specify the cryptographic mechanism used in modern access control systems (e.g. MIFARE DESFire) to prevent it.

Common mistakes and what to do instead

Recurring cryptographic failures in deployed systems follow identifiable patterns. The following catalogue covers the most common mistakes encountered in code review and penetration testing, with their security impact and the correct alternative. Each pair maps a specific failure to its mitigation.

  • Roll-your-own cryptography: designing a custom cipher, hash function, or protocol. Custom implementations invariably fail against attacks that standardised algorithms have been hardened against over decades of public cryptanalysis. The security of AES or SHA-256 is established by the absence of viable attacks after years of expert scrutiny — not by the elegance of the design. There is no practical context in which a custom cipher is preferable to a standardised one.
  • Hardcode secrets in source code or configuration files: API keys, symmetric keys, passwords and certificate private keys committed to version control are permanently exposed, regardless of subsequent deletion, because git history is preserved. Secrets in containerised images are similarly exposed in image layers.
  • Deprecated algorithms: MD5 (collision-broken, 2004), SHA-1 (collision-broken, 2017), DES (key-space exhausted, 1998), RC4 (keystream bias, RFC 7465 prohibition), and AES-ECB (IND-CPA insecure by construction) appear regularly in legacy systems and are routinely identified as critical findings in security audits.
  • Nonce reuse under AES-GCM: reusing a (key, nonce) pair with GCM exposes the GHASH authentication key H = EK(0), allowing an attacker to forge valid authentication tags for arbitrary ciphertexts under that key. A single nonce reuse compromises the integrity of all past and future messages under that key.
  • Fast hashes for password storage: storing passwords as SHA-256(password) or MD5(password) allows GPU-accelerated cracking at billions of guesses per second. A leaked database of fast-hashed passwords can be substantially cracked within hours.
  • Suppressing certificate validation errors: disabling hostname verification or accepting self-signed certificates unconditionally in production code removes the authentication guarantee of TLS, reducing it to unauthenticated encryption that is trivially defeated by MITM.
  • Use audited cryptographic libraries: libsodium (high-level, misuse-resistant API); platform APIs (OpenSSL/BoringSSL for TLS, Windows CNG, Apple Security framework); language-native crypto (Python cryptography, Java javax.crypto). Never implement primitives from specifications directly in application code.
  • Store secrets in dedicated secret management systems: HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager. Access is authenticated and audited; secrets are never persisted in application code or environment variables without an additional protection layer.
  • Use current algorithm recommendations: SHA-256 or SHA-3 for hashing; AES-256-GCM or ChaCha20-Poly1305 for authenticated encryption; X25519 or P-256 for ECDH; Ed25519 or ECDSA P-256 for signatures. Follow NIST SP 800-131A and SP 800-57 for algorithm transitions.
  • Generate nonces and IVs with a CSPRNG: never use a counter, timestamp, or sequential value as a GCM nonce with a static key. If nonce uniqueness cannot be guaranteed, use a nonce-misuse-resistant AEAD such as AES-SIV or XChaCha20-Poly1305.
  • Use Argon2id for password hashing: with memory and time cost parameters tuned so that a single hash takes approximately 100ms on the target hardware, with at least 64 MB of memory. bcrypt (work factor ≥ 12) is acceptable for legacy systems; scrypt is an alternative. PBKDF2 is acceptable when FIPS compliance is required.
  • Treat certificate validation failures as security events: a certificate error in a production system indicates a misconfiguration, an expired certificate, or a potential MITM attack. Logging, alerting, and rejection — not suppression — is the correct response.
NOTE

The practical principle underlying all of these: cryptographic primitives must be used within their defined security model. AES-GCM is secure when the nonce is unique per (key, message) pair; it catastrophically fails when this invariant is violated. RSA-OAEP is IND-CCA2 secure; textbook RSA is not. Argon2id is resistant to GPU cracking with appropriate cost parameters; SHA-256 is not a password hash. "We use AES" is not a security claim — the security claim requires specifying the mode, the key management, the nonce policy, and the authentication mechanism.

Review the following code fragment: key = "MySecretKey123"; cipher = AES.new(key, AES.MODE_ECB); ciphertext = cipher.encrypt(pad(plaintext)). Enumerate every security flaw, identify the specific attack or failure mode each flaw enables, and rewrite the call using AES-256-GCM with a CSPRNG-generated nonce and a key sourced from an environment variable retrieved at runtime.

Capstone: secure a clinic app in Dubai

A Dubai clinic is deploying a patient-facing application handling authentication, encrypted messaging, diagnostic results, and electronic prescriptions. The following threat model maps each data class and operation to its cryptographic protection requirements, the specific primitive and standard, and the relevant regulatory context. This is the kind of analysis expected in a security architecture review.

What needs protectingThe riskProtectionTool
Patient passwordsDatabase leak, mass crackingSalted slow hash + MFAArgon2id
App ↔ server trafficSniffing on café Wi-FiEncryption in transitTLS 1.3 (ECDHE + AES-GCM)
Medical records in the databaseStolen disk or backupEncryption at rest; keys kept separatelyAES-256 + cloud KMS
Doctor–patient chatProvider or insider reading messagesEnd-to-end encryptionSignal Protocol
E-prescriptionsForgery, or a doctor denying itDigital signatureECDSA or RSA signature
Lab result PDFsTampering after issueHash + signatureSHA-256, signed
NOTE

UAE Federal Law No. 2 of 2019 on the Use of Information and Communication Technology in Health Fields mandates that health data be stored within the UAE, with tightly constrained exceptions for cross-border transfer. Encryption protects data confidentiality; it does not satisfy the data residency requirement, which is a legal and jurisdictional constraint enforced at the infrastructure level (cloud region selection, data processing agreements). Both requirements must be addressed independently.

Extend the threat model with two additional rows: (1) appointment SMS reminders sent via a third-party gateway, and (2) staff laptops containing locally cached patient records. For each: identify the threat actors, specify the applicable cryptographic controls and their limitations, identify any residual risks that cryptography alone cannot address, and reference the relevant standard or regulation.

Check yourself: six questions

These questions test precision of reasoning, not recall. A correct answer must reference the specific security property or formal concept, not just name the algorithm. Attempt each before reading the answer.

1

Decrypt the ciphertext KHOOR under a Caesar cipher with k = 3. State the formal decryption function and apply it.

Dk(C) = (C − k) mod 26. K → H, H → E, O → L, O → L, R → O: plaintext is HELLO. Observation: the full 25-key space is exhausted in under a second by script — the cipher fails catastrophically regardless of the key choice.

2

AES-ECB is applied to a structured database. Precisely why does this fail the IND-CPA security definition?

A deterministic cipher cannot be IND-CPA secure: an adversary who submits two plaintext blocks m0 = m1 as a challenge can distinguish EK(m0) from EK(m1) with advantage 1 because EK(m) = EK(m') iff m = m'. ECB also reveals block equality across the entire ciphertext, enabling structural inference (frequency analysis at the block level).

3

How many pairwise symmetric keys do 20 parties require for all-pairs private communication? How does this change with public-key cryptography?

20 × 19 / 2 = 190 pairwise keys with symmetric cryptography. With asymmetric cryptography: each party generates one key pair; 20 parties require 20 key pairs (40 key values) regardless of the communication pattern. The asymmetric solution scales as O(n) rather than O(n2).

4

With p = 23, g = 5, A = ga mod p = 8: recover Alice's private exponent a. Explain why the same computation is infeasible for real DH parameters.

Enumerate: 51 = 5, 52 = 2, 53 = 10, 54 = 4, 55 = 20, 56 = 8 mod 23 → a = 6. This is the discrete logarithm problem (DLP) in Z23*. For a 2048-bit prime, the best known algorithm (GNFS) requires sub-exponential time L[1/3, ≈1.9] evaluations — computationally infeasible with current hardware.

5

HMAC and a digital signature both authenticate a message. Which provides non-repudiation, and why can't the other?

A digital signature provides non-repudiation: the signing key sk is held exclusively by the signer, so a verifier who confirms Verify(vk, m, σ) = accept can attribute σ to the holder of sk. HMAC uses a shared symmetric key K: any party holding K can compute HMAC(K, m), so a valid MAC cannot be attributed to one specific party — either could have produced it. Non-repudiation requires a secret held by exactly one party.

6

Salting and a memory-hard hash function are both recommended for password storage. They defeat different attacks. Specify which attack each defeats and explain the mechanism precisely.

Salt defeats precomputation attacks (rainbow tables): a per-user random salt s ensures that Argon2id(s, p) ≠ Argon2id(s', p) even when p is identical, forcing per-user independent cracking. Memory-hard parameters defeat online guessing at scale: if each hash evaluation requires 100ms and 64 MB, an attacker with a GPU cluster can test at most ~104 guesses/second/GPU rather than ~1010 for SHA-256, increasing cracking time by six orders of magnitude for the same hardware budget.

NOTE

Select any HTTPS service you use regularly. Using browser developer tools or openssl s_client, inspect: the TLS version, the negotiated cipher suite (ECDHE group, AEAD algorithm, PRF hash), the certificate chain length, the issuing CA, and whether HSTS is enforced. Identify any configuration that deviates from current best-practice recommendations (RFC 8446, BSI TR-02102-2, or NIST SP 800-52r2) and explain the security implication.

Stay in the work

YouTube — Subscribe · @sam_mk87

LinkedIn — Connect · where I publish the thinking

X — Follow · @sam_mk87

Instagram — Follow · @sam__mk87

Website — sammokhtari.com · writing and advisory