In the previous blog, “Detecting the mode of block cipher being used” was discussed. In this blog, the second step in the attacking of a block cipher i.e. detecting the block size of the cipher, will be discussed. Link to the implementation script has been given at the end of this post which is written in python.
We need to closely look at the padding implementation in the block cipher in order to get the size of the block used. It is good that we list down the key points: the ones that are given and the ones that are needed to be found out, before jumping to the padding function:
- The mode used for encryption.
- The standard block cipher encryption used.
- The encryption function.
- The padding function.
One needs to find out the size of block used, having access to the above things. If you closely looks at how padding is implemented in any oracle function, you can observe that the number of bytes to be padded is the minimum number of bytes required to be added to the plaintext string, such that the length of the padded string becomes a multiple of the block-size. But a thing to be mentioned here is that the number of bytes to be padded should have a minimum value of 1 and maximum value equal to the block-size.
For example, let the block-size of the cipher be 16 bytes and length of input string be 7 bytes. This gives the number of bytes to be padded equal to 16 – 7 = 8. When the input string is 18 bytes long then the number of bytes to be padded is equal to 16*2 – 18 = 14. When the input string is 16 then the number of bytes to be padded is 16. Generalizing it:
padlen = n - (l % n)
where “padlen” is the number of bytes to be padded, “n” is the block size and “l” is the length of the original unpadded string.
When one encrypts this padded string, the length of the ciphertext remains the same. One catch in the padding function, the length of the ciphertext remains the same when one increases the length of the input string by one each time, until the length of the input string becomes a multiple of the block-size because then an entire block will be added to the plain-text string having length equal to the block-size.
So, to detect the size of the block cipher, one can simply call the encryption function each time, giving a single character as an input and noting the length of the ciphertext for each time. Keep on appending single characters to the input string each time and note down the length of ciphertext each time and checking if the length of the ciphertext generated in the current iteration is equal to the one generated in the previous iteration or not. If not, then one can conclude that an entire block has been added to the original string, and hence the size of the block is equal to the difference between the length of the original string when the length of the ciphertext just changed and the length of its corresponding ciphertext.
Here is the implementation of the exploit:
Cheers! All Hail Cryptography!