Hash Length Extension Attack

A browser port of hash_extender

This page could not start. Browsers block JavaScript modules loaded over file://, so opening the .html straight from disk will not work. Serve the directory over HTTP instead — from the project folder run python3 -m http.server and open http://localhost:8000/. (Deployed on GitHub Pages this does not apply.)

Background

MD4, MD5, SHA-1 and SHA-2 all use the Merkle–Damgård construction: the message is padded to a whole number of blocks, and each block is fed through a compression function that updates a small internal state. When the last block is done, that state is the digest.

So a digest is a resumable checkpoint. This is the whole reason the attack works. Applications commonly adopt the H(secret || data) construction to prove that the data they issued comes back untampered. Publishing both the data and its hash makes it possible to extend the hash with arbitrary data. You can append your own bytes and produce a hash the server will accept, without ever learning the secret.

The one catch is padding. The original hash internally padded secret || data out to a block boundary, so your appended bytes actually land after that padding. The forged message therefore has to carry that padding in the middle of it. This includes the \x80\x00\x00... run plus a length field, known as glue padding.

What this tool does

Given it the hash, the known data it covers, what you want to append, and the secret's length in bytes, you can append data without knowning the secret. It returns the forged hash and the new message. Supported algorithms are sha256, sha1, sha512, md5, md4, ripemd160, ripemd128, sm3, whirlpool, tiger192v1 and tiger192v2. Data and appended data can be entered as text or as hex.

It will not help you against SHA-3 or BLAKE2, which are built so that the digest never exposes the whole internal state. Nor against SHA-384 or SHA-512/256, which truncate a SHA-512 state and withhold 128 and 256 bits respectively.

This is a direct JavaScript port of iagox86/hash_extender by Ron Bowes (BSD 3-Clause). The padding and extension logic are ports of that project's hash_append_data() and hash_gen_signature_evil(). All credit for the tool and the technique writeup goes there.

The attack

Result

New hash


    

New data


    

New data — escaped


    
Check the forgery (optional — needs the secret)

If you happen to know the secret, this proves the attack end to end: it recomputes H(secret || data) to confirm it matches your signature, then recomputes H(secret || new data) to confirm it matches the forged one. Useful for building a demo, or for sanity-checking a target's key length.

Further reading

Plenty of people have already explained this attack well, so rather than write another version, here are the ones worth your time:

Credits

Ported from hash_extender by Ron Bowes.