Pad a message, and read its sixteen words in the four orders MD5 uses. Step through one of the 64 steps. Then see two different messages that have the same digest.
MD5demo
Objectives
Describe MD5 padding, including why the length is part of the input and why it is written low byte first.
Explain that MD5's schedule reorders sixteen words rather than expanding them, and name the four steps that read a given word.
Trace one MD5 step: which word it reads, which function it applies, and which of the four working words it computes.
Read the Wang and Yu collision as data: six differing bits, equal chaining states after the second block, equal digests.
State why a common suffix preserves that collision, and why a collision is still not a preimage.
Static site. Every demo computes in your browser, and nothing you type is sent anywhere.
25%
Padding, the sixteen words in four orders, one of the 64 steps, and the published collision.
MD5 reads a message as 64-byte blocks. A message is almost never a whole number of blocks, so the first thing the function does is add padding: a single 1 bit, written as the byte 0x80, then zeros, then the length of the original message in bits. Type anything below and watch the padding move.
The message is 3 bytes, so the length field holds 24 bits. MD5 writes that number with its low byte first, which is why it appears as 1800000000000000 rather than at the other end. Padding is never skipped: a message that is already a whole number of blocks gets a whole block of padding, because the length has to be in there.
blocks after padding
1 block of 64 bytes
The length is part of the input, not bookkeeping. Two messages of different lengths can never reach the compression function with the same final block, which is the property the Merkle–Damgård argument needs.
Each block is sixteen 32-bit words, read low byte first. MD5 runs 64 steps over them, in four rounds of sixteen, and every step reads exactly one of those sixteen words. It never computes a new one.
For abc, X[0] is 80636261: the three letters 61 62 63 and then the padding byte, read back as one little-endian word. Byte order is the whole difference here. SHA-1 and SHA-256 read the same block the other way round.
Which word each step reads
The four rows below are the four rounds. Each row lists the word index of its sixteen steps in order, from the rules i, 5i+1, 3i+5, 7i, all taken modulo 16.
Word 0 is read at steps 1, 20, 42 and 49. A difference placed in one message word therefore enters the computation at four known points, and an attacker who is choosing differences knows exactly where they land. That is not a flaw on its own — SHA-256 expands sixteen words into sixty-four instead, which spreads a difference rather than repeating it — but it is what makes MD5's differential paths tractable to search for.
One step changes one of the four working words and moves the other three along. Drag the slider to walk through the 64 steps of the first block.
a ← b + ROTL(a + F(b, c, d) + T[i] + X[k], s), then rotate the four words
Step 1 of 64
step
1
117334964
round 1
function F
word X[0]
rotate 7
T[1] = d76aa478
the working words, before and after
a b c d
before 67452301 efcdab89 98badcfe 10325476
after 10325476 d6d117b4 efcdab89 98badcfe
Three of the four words simply shift position: the b, c and d that go in come out as c, d and a. Only one new word is computed, and it is the one written into b. Sixty-four steps of this give every word sixteen turns at being the computed one.
The round function changes every sixteen steps. F uses each bit of b to choose between c and d; G does the same with d choosing; H is a plain XOR of the three; I is the fourth. All four are cheap on 1992 hardware, which is the reason there are four of them rather than one good one.
After the last step the four working words are added back into the state the block started from. That addition is the feed-forward, and it is what stops the 64 steps from simply being run backwards.
Finishing a block, and the digest
block 0
a b c d
state in 67452301 efcdab89 98badcfe 10325476
after 64 steps 310ade8f c08226b3 e484b9d8 624d8cb2
state out 98500190 b04fd23c 7d3f96d6 727fe128
Each output word is the sum of the two lines above it, keeping the low 32 bits. With one block, that state is the digest, written low byte first.
MD5 of the message above
900150983cd24fb0d6963f7d28e17f72
And this is why MD5 is not used
Wang and Yu published two 128-byte messages with the same MD5 digest in 2005. Both are below. They are not close to random pairs: they were constructed, and the search that produced them took hours on the hardware of the day rather than the 264 a 128-bit digest suggests.
The word differences between the two colliding messages, by block and word index.
Block
Word
Difference, B minus A
0
4
-2^31
0
11
+2^15
0
14
-2^31
1
4
-2^31
1
11
-2^15
1
14
-2^31
Six words differ, each by a single power of two, at byte offsets 19, 45, 59, 83, 109, 123. The whole distance between two messages that MD5 cannot tell apart is six bits.
the chaining states, block by block
after block 0 80000000 82000000 86000000 82000000
after block 1 00000000 00000000 00000000 00000000
Those lines are the XOR of the two states, so all-zero words mean the states are equal. The first block leaves them different on purpose; the second block is built to cancel that difference. After 128 bytes the two messages are in exactly the same state, at a block boundary, with the same number of bytes processed.
the same suffix added to both
A + suffix 70f28864c699ecebb678cf6b80a681ee
B + suffix 70f28864c699ecebb678cf6b80a681ee
Equal states and equal lengths mean equal padding and equal digests from there on, so anything appended to both keeps the collision. That is what turns a pair of meaningless byte strings into a pair of files: give them a common tail, and whatever a signature covers, it covers both.
A collision is not a preimage. Nothing on this page lets an attacker take a digest they were handed and find a message for it. What it does let them do is prepare two documents in advance and get one of them signed. Which of the three properties an application actually needs is the question to ask before calling a broken hash a problem, or calling an unbroken one safe.
The code behind this page is a teaching implementation. It is written to be read, it is not constant time, and it is not for production use. MD5 should not appear in a new design at all.