I didn't get the hash length extension attacks I was trying to solve a cryptography challenge and the problem was about "hash length key extension". After some reading in different topics, I don't know why I still didn't solve the challenge.

I read this page. From what I understood, we have the MAC which is $\mathrm{md5}(\mathrm{secret}||\mathrm{data})$.  We want to append some string at the end, so we will have the new hash $\mathrm{md5}(\mathrm{secret}||\mathrm{data}||\mathrm{append})$.

When I run $\mathrm{md5}(\mathtt{secretdata})$, I get 6036708eba0d11f6ef52ad44e8b74d5b like in the tutorial.
But when I compute $\mathrm{md5}(\mathtt{secretdataappend})$, I get 81efe001a23d41765fa7323d22861558. However, the tutorial says it should be 6ee582a1669ce442f3719c47430dadee.

In other tutorials it is the same hash value, so I am probably doing something wrong. My instinct is that I have to guess the value of $\mathrm{secret}||\mathrm{data}||\mathrm{append}$, without knowing $\mathrm{secret}$. I only know the length of $\mathrm{secret}$.

Why do I get the wrong hash when trying to perform this attack?
OK, so the general idea of MD5 and SHA-1 and SHA-2 is that they process the data in blocks. For the last block the algorithms first append a padding to the plaintext data and the encoding of the length to create the final block. If the padding and length do not fit then an additional block is used.

Now the problem with these algorithms is that the intermediate state, that is: the state after a block encrypt is directly used as the output for the final block. So if you have three blocks then the value of the last block operation is used as output. So if you have a message that consists of the first block and then two blocks that mimic the last part of the message, padding and length indication then the intermediate value between block 3 and block 4 will be identical to the output of the previous calculation. After that you can add any data and keep processing as usual.

Let's put this in a scheme, ignoring the secret for now:

| message_b1 | message_b2 | message_p3 | padding_p3 | length__p3 |
| process_b1 | process_b2 |              process_p3              |
| h_state_b1 | h_state_b2 |              h_state_p3              |


can be extended using

| message_b1 | message_b2 | message_b3 | message_p4 | padding_p4 | length__p4 |
| process_b1 | process_b2 | process_p3 |              process_p4              | 
| h_state_b1 | h_state_b2 | h_state_p3'|              h_state_p4              |


For this to happen message_b3 must of course consist of message_p3 | padding_p3 | length__p3 otherwise h_state_p3' will be different from h_state_h3 and therefore h_state_p4 the final output will be invalid.

If the secret is (part of) message_b1 then the verifier will automatically prefix the secret for you. So you just need to provide the message itself, but it must consist of the special format.



SHA-3 post processes the hash, so the length extension is not possible anymore as the final hash cannot be an intermediate value of another hash calculation.