← All Tools

How HMAC Blocks Length-Extension Attacks — The ipad/opad Double-Hash Structure Explained

Guide · Last verified Aug 28, 2026

When you're writing API signature or webhook verification code, it's natural to think "why not just hash SHA-256(secret key + message)?" Intuitively it seems safe, since only someone who knows the key could produce the same hash. But this approach is directly exposed to a structural flaw baked into how hash functions like SHA-256 actually work internally: the length-extension attack. Understanding exactly how this attack works is what makes it clear why HMAC (RFC 2104) bothers with the seemingly roundabout step of mixing the key in twice, through a double-hash structure.

1. Why "concatenate key + message" is dangerous

Hash functions like SHA-256 internally use the Merkle-Damgård construction. The message is split into fixed-size blocks (64 bytes for SHA-256); the first block is fed into the compression function together with an initial state to produce the next state, and that state is then fed into the compression function again along with the next block — this repeats through the final block. The resulting hash value is, in fact, nothing more than "the internal state after processing every block of the message." There's no separate finalization step — the last internal state simply *is* the output. That's the key point.

This is exactly why it's dangerous. If an attacker knows the hash value SHA256(key + message) and the length of message (the exact byte count, including padding rules), they can reuse that hash value directly as "an internal state from which computation can be resumed." In other words, without ever knowing the contents of the original key+message, they can produce a valid hash for a new message — key+message+padding+extra — that appends whatever data they want, without recomputing anything from scratch. Since the server has no way to distinguish this from a value the legitimate signer produced, if it accepts this value at face value, it ends up approving a forged request where the attacker has secretly added extra parameters. Being able to forge a signature without ever knowing the key is what makes this attack a real threat.

2. How the ipad/opad double hash blocks this

HMAC is defined as: HMAC(K, m) = H((K⊕opad) ∥ H((K⊕ipad) ∥ m)). Here, ipad is a padding value made of 0x36 repeated to fill a block, and opad is 0x5c repeated the same way. The key K is XORed with each of these separately, the inner hash is computed first, and that result is fed into the outer hash for one more round of hashing. On the surface this just looks like "hashing twice," but the real reason this structure blocks length-extension attacks is that the final output is no longer "the last internal state after processing the message."

In the naive concatenation scheme, the hash value an attacker holds in hand was literally the internal state. But in HMAC, all an attacker ever sees is the final output of the outer hash H((K⊕opad) ∥ inner-result) — and to even begin computing that outer hash in the first place, you need to start from K⊕opad, a value that's impossible to know without the key. Even if an attacker wanted to "resume computation" from this final output, restarting at that point would require knowing the secret value K⊕opad, which is information they simply cannot obtain. Ultimately, it's the fact that the key is involved twice — at both the start and the end of the message-processing path — that turns the final hash value from "a state you can extend" into "a self-contained, completed result." The reason ipad and opad are deliberately different values is so that the key-XOR results feeding the inner and outer hashes differ from each other, making the two hash computations behave like fully independent functions and leaving an attacker no relationship between them to exploit.

In short: with a naive hash SHA256(key+message), the result equals "the internal state after processing the message," so computation can be resumed from it. HMAC feeds the inner hash result into a second, outer hash so that the key is involved twice, making it impossible to ever recover that inner computation state from the final output alone. This asymmetry is what shuts down length-extension attacks at the root.

3. Why HMAC is the standard for API signatures and webhook verification

The reason services like GitHub and Stripe always attach an HMAC signature in the header when sending webhook payloads comes down to this structural safety. A webhook is an HTTP request sent to a public URL, so anyone can send a fake request that mimics its format. The receiving server just needs to compute the same signature itself, using a shared secret key it already knows, and compare it against the signature that arrived with the request body — a simple, fast implementation. If that signature computation used a naive concatenation hash instead, an attacker could produce a valid signature for a tampered request with malicious fields appended after the original payload, making the verification meaningless. With HMAC, this kind of forgery is mathematically impossible without the key, which is why "shared secret key + HMAC" has become the lightest-weight way to achieve both sender authentication and integrity verification at once, without needing any separate public-key infrastructure.

Frequently Asked Questions

Q. What exactly is a length-extension attack?

A. It's an attack where, without knowing the contents of the original message, an attacker who only knows its hash value and length can compute a valid hash for a new message that appends arbitrary data after the original. Hash functions built on the Merkle-Damgård construction — SHA-256, SHA-1, MD5 among them — are all subject to this issue.

Q. Why is it dangerous to just concatenate the key and message?

A. Because a value like SHA256(key + message) is actually identical to the hash function's internal state at the moment it finishes processing the message. An attacker can resume computation from that internal state and produce the hash of a new message — the original plus appended data — without ever knowing the key.

Q. Why do ipad and opad prevent this problem?

A. HMAC doesn't place the key in front of the message — it mixes the key into a double-hash structure with two different padding values, deep inside the computation. From the final output of the outer hash H(key⊕opad ∥ inner-result) alone, an attacker has no way to reconstruct that internal state, so the extension attack simply doesn't work.

Q. Why is HMAC the standard for verifying webhook signatures?

A. Webhooks are data sent to a public URL, so tamper detection is essential. With HMAC, the sender and receiver only need a shared secret key to each independently compute the same signature value and compare them, and because it's also immune to length-extension attacks, most API providers — GitHub, Stripe, and others — have adopted it as the standard.

Q. Does using SHA-3 instead of SHA-256 eliminate this problem entirely?

A. Yes. SHA-3 (Keccak) uses a sponge construction rather than Merkle-Damgård, so a length-extension attack isn't even possible against it in the first place. That said, today's API ecosystem overwhelmingly standardizes on SHA-256-based HMAC, so in practice it's more common to simply keep using the already-secure HMAC construction.