One way to carry out the chosen-prefix ECB mode attack you describe is as follows:
Step 1: Obtain the ciphertexts corresponding to the following 16 plaintexts, where each X
denotes a known byte (typically, part of our chosen prefix), each ?
denotes a byte of the (fixed) unknown suffix that we wish to decrypt, and spaces show the boundaries of the 16-byte AES cipher blocks:
XXXXXXXXXXXXXXX? ???????????????? ???????????????? ???????????????...
XXXXXXXXXXXXXX?? ???????????????? ???????????????? ??????????????...
XXXXXXXXXXXXX??? ???????????????? ???????????????? ?????????????...
XXXXXXXXXXXX???? ???????????????? ???????????????? ????????????...
XXXXXXXXXXX????? ???????????????? ???????????????? ???????????...
XXXXXXXXXX?????? ???????????????? ???????????????? ??????????...
XXXXXXXXX??????? ???????????????? ???????????????? ?????????...
XXXXXXXX???????? ???????????????? ???????????????? ????????...
XXXXXXX????????? ???????????????? ???????????????? ???????...
XXXXXX?????????? ???????????????? ???????????????? ??????...
XXXXX??????????? ???????????????? ???????????????? ?????...
XXXX???????????? ???????????????? ???????????????? ????...
XXX????????????? ???????????????? ???????????????? ???...
XX?????????????? ???????????????? ???????????????? ??...
X??????????????? ???????????????? ???????????????? ?...
???????????????? ???????????????? ???????????????? ...
Note that, for this step, it doesn't matter what the known prefix bytes denoted by X
actually are. The prefixes can all be different, and they don't even have to be chosen by us, as long as all of them are known to us and have distinct lengths (modulo 16).
Step 2: From the ciphertexts obtained in step 1, find a block for which we already know all but one the plaintext bytes (e.g. XXXXXXXXXXXXXXX?
). Obtain the encryptions of all the 256 possible values of that plaintext block, i.e. with the known bytes kept fixed and the missing byte set to all of its 256 possible values, and check which of the resulting ciphertext blocks matches the ciphertext obtained in step 1. (Note that you can do this with a single 256-block chosen plaintext query to the encryption oracle.) This will tell us the value of the missing byte.
Now that we've determined the value of the missing byte (say, a
), it becomes part of the known prefix. Thus, we now know that the ciphertexts from step 1 actually correspond to the following partially known plaintexts:
XXXXXXXXXXXXXXXa ???????????????? ???????????????? ???????????????...
XXXXXXXXXXXXXXa? ???????????????? ???????????????? ??????????????...
XXXXXXXXXXXXXa?? ???????????????? ???????????????? ?????????????...
XXXXXXXXXXXXa??? ???????????????? ???????????????? ????????????...
XXXXXXXXXXXa???? ???????????????? ???????????????? ???????????...
XXXXXXXXXXa????? ???????????????? ???????????????? ??????????...
XXXXXXXXXa?????? ???????????????? ???????????????? ?????????...
XXXXXXXXa??????? ???????????????? ???????????????? ????????...
XXXXXXXa???????? ???????????????? ???????????????? ???????...
XXXXXXa????????? ???????????????? ???????????????? ??????...
XXXXXa?????????? ???????????????? ???????????????? ?????...
XXXXa??????????? ???????????????? ???????????????? ????...
XXXa???????????? ???????????????? ???????????????? ???...
XXa????????????? ???????????????? ???????????????? ??...
Xa?????????????? ???????????????? ???????????????? ?...
a??????????????? ???????????????? ???????????????? ...
Now, one of these plaintext blocks (e.g. XXXXXXXXXXa?
) again contains only one unknown byte. Thus, we can repeat step 2 above, following the same procedure as before to determine the value of the next unknown byte (let's say it's b
), which again becomes a part of the known prefix. Then we can again repeat step 2, this time with the partially known plaintext block XXXXXXXXXab?
and thus obtain the third byte of the suffix, and so on.
In particular, after repeating step 2 sixteen times, we will have determined the first 16 bytes of the suffix (say, abcdefghijklmnop
). Thus, we now know that the ciphertexts obtained in step 1 correspond to the following partially known plaintexts:
XXXXXXXXXXXXXXXa bcdefghijklmnop? ???????????????? ???????????????...
XXXXXXXXXXXXXXab cdefghijklmnop?? ???????????????? ??????????????...
XXXXXXXXXXXXXabc defghijklmnop??? ???????????????? ?????????????...
XXXXXXXXXXXXabcd efghijklmnop???? ???????????????? ????????????...
XXXXXXXXXXXabcde fghijklmnop????? ???????????????? ???????????...
XXXXXXXXXXabcdef ghijklmnop?????? ???????????????? ??????????...
XXXXXXXXXabcdefg hijklmnop??????? ???????????????? ?????????...
XXXXXXXXabcdefgh ijklmnop???????? ???????????????? ????????...
XXXXXXXabcdefghi jklmnop????????? ???????????????? ???????...
XXXXXXabcdefghij klmnop?????????? ???????????????? ??????...
XXXXXabcdefghijk lmnop??????????? ???????????????? ?????...
XXXXabcdefghijkl mnop???????????? ???????????????? ????...
XXXabcdefghijklm nop????????????? ???????????????? ???...
XXabcdefghijklmn op?????????????? ???????????????? ??...
Xabcdefghijklmno p??????????????? ???????????????? ?...
abcdefghijklmnop ???????????????? ???????????????? ...
Note that now we again have a ciphertext block corresponding to a plaintext block with just one unknown byte: this time, it's bcdefghijklmnop?
, consisting of the now known bytes 2 to 16 of the suffix, and the yet unknown 17th byte. Thus, we can again repeat step 2 above to find out the value of the 17th byte, and we can keep repeating the same process over and over until we've finished decrypting the entire suffix.