Reading — step 1 of 5
Read
~2 min readPadding & Length
Length-Extension Attack
You hashed a secret-prefix MAC: tag = SHA-256(secret || message). Anyone who knows tag and the message length can forge SHA-256(secret || message || glue || suffix) for ANY suffix they choose — without ever learning secret.
This is why bare SHA-256 (and SHA-1, SHA-512) is unsafe as a MAC, and why HMAC exists.
Why it works
The output of SHA-256 IS the internal state after the last block was absorbed. Given tag = SHA(M), an attacker can:
- Parse
taginto 8 big-endian uint32s — that's the state(a,b,c,d,e,f,g,h). - Compute the glue padding that was applied to
M: the0x80byte, zero padding to 448 mod 512 bits, plus|M|in bits. - Continue the SHA-256 algorithm from the recovered state with ANY suffix, padding it as if
|M| + |glue|bytes had already been processed. - The resulting hash equals
SHA(M || glue || suffix).
A concrete attack
secret = "supersekret" (unknown to attacker, 11 bytes)
message = "user=guest&role=user" (visible to attacker)
tag = SHA-256(secret || message) (visible — published as the MAC)
The attacker:
state = parse(tag) # 8 uint32 words
glue = pad_for_length(11 + 20) # 0x80 + zeros + 64-bit (31*8)
forged = continue(state, "&role=admin", processed = 11 + 20 + |glue|)
# Server then computes:
real = SHA-256(secret || message || glue || "&role=admin")
# real == forged. The attacker promoted themselves to admin.
Defenses
| Construction | Length-extendable? |
|---|---|
SHA-256(secret || M) | Yes — broken |
SHA-256(M || secret) | Yes (but harder; collision exposes secret) |
| HMAC-SHA-256 | No |
| SHA-3 (Keccak) | No (sponge) |
| BLAKE2/BLAKE3 | No (keyed mode) |
Always use HMAC when you need a MAC from SHA-2. The double-hash structure of HMAC prevents the attacker from continuing from the published tag.
Real-world incidents
- Flickr API (2009): used
MD5(secret || params)for signing — patched by switching to HMAC. - Microsoft ASP.NET (2010, "Padding Oracle"): a different but related family of issues with crypto primitives misused.
- Many home-grown auth schemes: any time you see
hash(key || ...)in API signing, it's worth checking.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…