Hash Lab

Tool · Attack demo

Length-extension Attack

A live demonstration of why H(secret ∥ message) is not a secure MAC. Knowing only the original digest and the length of the secret, an attacker can compute a valid digest for the original message plus arbitrary appended data , without ever seeing the secret.

1. The victim signs a message with a naive prefix MAC: H(secret || message)

Actual length: 16 bytes

Naive MAC = SHA-256(secret ∥ message)

07e124bcd33c54b741e9b58dbedeff3e09bd1fe040c49de4d064bc452f268b8c
2. Attacker knows the MAC and the length of the secret. Forges a valid MAC for a longer message, without the secret.

If you guess wrong, the forgery breaks. Attackers brute-force this in seconds (1-32 byte search).

Forged body (message ∥ origPadding ∥ extension):

amount=100&to=alice\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x18&to=mallory&amount=99999
Lengths (bytes): message 19 · padding 29 · extension 24
Padding hex: 8000000000000000000000000000000000000000000000000000000118

The pink section is the padding the victim’s hash internally added to the original message. The attacker re-emits it as literal data, so when the victim hashes secret ∥ forgedBody they reproduce the same intermediate state the original MAC ended in.

Forged MAC (computed without the secret):

1ad29a681c6260237c70b07e206a2fd7c933d8edce024b65cdaffb8ac231086a
3. Victim re-hashes secret ∥ forgedBody and compares

Direct H(secret ∥ forgedBody): 1ad29a681c6260237c70b07e206a2fd7c933d8edce024b65cdaffb8ac231086a

Match, the forgery is indistinguishable from a legitimate MAC.

Why this works

SHA-256 is a Merkle-Damgård hash. Its 256-bit output is the internal state at the end of the last compression. Anyone who has the digest can resume hashing , they just need to know how many bytes were already absorbed so they can supply the same length-encoded padding the original sender would have. If the attacker controls the appended bytes, they get a valid digest for secret ∥ original ∥ origPadding ∥ extension.

The Flickr 2009 vulnerability is the classic real-world example: their signed-URL scheme used md5(secret + params), lettings anyone with one valid URL forge URLs with extra parameters. Amazon S3 query-string authentication once had a similar shape.

Mitigations (any of these are sufficient)

  • Use HMAC.HMAC’s nested structure binds the key inside both passes and is immune. See the HMAC playground.
  • Use a hash without this property. SHA-3, BLAKE2, BLAKE3, SHA-512/256, and SHA-384 are not vulnerable.
  • Apply the hash twice: H(H(key ∥ message)) (Bitcoin’s SHA-256d) blocks length-extension. Less general than HMAC; use HMAC unless you have a reason.
  • Or just sign instead of MAC. Asymmetric signatures do not have this footgun.

FAQ

Frequently asked questions