I am newbie to CBC crypto: When I try decrypt the cipher text to recover the plain text, things are not going smoothly as I face some issues in the decryption process with padding and not obtaining the plain text finally.

So I would like to know about why padding is used in this CBC method? Why is it not used in the ECB method? Should we pass padding for the decryption process?

Below are the cipher text and IV which I have used in my testing:

cipher text(hex) - 6d 25 1e 90 44 b0 51 e0 4e aa 6f b4 db f7 84 65

Initialization Vector(hex) - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Expected Plain text(hex) - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Could someone try this ciphertext and IV and share the results?

Key size: 16;

Key used in hex: 10a58869 d74be5a3 74cf867c fb473859

  • 1
    $\begingroup$ And what key are you using? If it were the all-zero key, you should have 8A05FC5E095AF4848A08D328D3688E3D as a ciphertext... You can test your AES-CBC using the test vectors one can find all over the internet. For example here. $\endgroup$
    – Lery
    Jun 26 '17 at 8:24
  • $\begingroup$ Hello Lery, could you please check are you getting expected plain text with the key mentioned? Thanks for your response $\endgroup$
    – danny
    Jun 26 '17 at 10:37
  • 1
    $\begingroup$ I've completed my answer with a practical part. But it works fine for me, as long as I don't forget to "reset" the IV back to its original value before decryption. $\endgroup$
    – Lery
    Jun 26 '17 at 12:35
  • 2
    $\begingroup$ Are you sure the ciphertext is not "6d 25 1e 69 44 b0 51 e0 4e aa 6f b4 db f7 84 65"? $\endgroup$
    – fgrieu
    Jun 26 '17 at 18:14

So, I'll answer the theoretical part of your question, since we need a key to address the practical part.

Why is padding used in CBC?

Blockcipher such as AES are encrypting blocks of a fixed given size only, we call it the "blocksize". So, what if your data is smaller than the blocksize ? An easy solution is to add what we call "padding" to your plaintext in order to have its size match the block size. So, padding is there to allow you to encrypt data smaller than the blocksize... But what if you want to encrypt something bigger than your blocksize?

That's where the mode of operations, such as CBC, come into play. Modes of operations are there to allow you to encrypt more data than the blocksize of your symmetric blockcipher.

But since those modes of operation are still using the underlying blockcipher to encrypt data, it means that they can only encrypt a multiple of the blocksize. So, if you have $4\ell$ bits of data to encrypt, for $\ell$ the block size of your cipher, then you're fine. But what if you have $4\ell+5$ bits of data? (I am assuming the blocksize does not divide 5.) Then you need to pad the data with $\ell-5$ bits of padding in order to end up with a multiple of the blocksize of data ready for encryption with your mode of operation.

There are multiple methods to pad data, which can completely undermine the compatibility of a given encryption program with others. The most used padding method in symmetric ciphers and mode of operation is certainly PKCS#7.

Worth noting

There exists methods to avoid padding, in order to avoid padding completely so the ciphertext is the same size as the plaintext, the most common of those methods is certainly the one called ciphertext stealing.

There also exists modes of operation, such as CTR, which do not need any padding.

Now, contrarily to RSA encryption for instance, padding in symmetric encryption does not add security.

Checking the padding upon decryption can allow to catch errors in the transmitted ciphertext, because of the avalanche effect, (depending on the mode of operation used), but can also lead to terrific padding oracle attacks.

As explained in that question, it is better to use a cryptographic MAC to protect your ciphertext, and verify it first before performing decryption or even padding checks. I also refer you to that legendary question, regarding the way one should MAC its data when using encryption.

About ECB

Actually ECB also encrypts only multiples of the blocksize, so you will also need padding or another method to have enough data to encrypt. However, you should not use ECB for the reasons pointed out there.

Regarding your practical problem

So, I've tried your values:

from Crypto.Cipher import AES
import binascii

key = binascii.unhexlify("10a58869d74be5a374cf867cfb473859")
iv = binascii.unhexlify(16*"00")

plaintext = binascii.unhexlify(16*"00")
ciphertext = binascii.unhexlify("6d251e9044b051e04eaa6fb4dbf78465")

ciph = AES.new(key, AES.MODE_CBC, iv)

test1 = ciph.encrypt(plaintext)
print("The ciphertext is what we expected:", test1==ciphertext)    

#We need to reset the cipher to get the correct IV
ciph = AES.new(key, AES.MODE_CBC, iv)

test2 = ciph.decrypt(ciphertext)
print("The recovered plaintext is what we expected:", test2 == plaintext)

and as you can see if you try it with Python and PyCrypto, it works but your ciphertext strangely differ from the actual value at offset 4, as pointed in the comment by fgrieu. The actual value is 69, not 90.

This error at offset 4 explains why you couldn't get the correct recovered plaintext, because of the avalanche effect, the whole AES block was being impacted by that little mistake.

  • 1
    $\begingroup$ Exactly how did you get "6d251e6944b051e04eaa6fb4dbf78465"? It is nowhere to be found in the question, which has the different "6d 25 1e 90 44 b0 51 e0 4e aa 6f b4 db f7 84 65" (in every version that I could find)? $\endgroup$
    – fgrieu
    Jun 26 '17 at 18:14
  • 1
    $\begingroup$ sorry that the cipher text is absolutely right as mentioned by lery "6d251e 69 44b051e04eaa6fb4dbf78465" since 90 is not right value. $\endgroup$
    – danny
    Jun 26 '17 at 18:21
  • 2
    $\begingroup$ @fgrieu I actually completely missed it and I guess I've wrongly copy-pasted the ciphertext from my terminal instead of the question. You are right that they differ. But I got the actual value when encrypting using the provided parameters. I'll edit it to point it out. $\endgroup$
    – Lery
    Jun 26 '17 at 18:40
  • 1
    $\begingroup$ 'Why not ECB?' Like CBC, ECB is block-oriented and does require padding for most data; what it does not require is an IV. However, ECB often allows the overall system to be broken, which makes the padding unimportant in comparison. Consider a restaurant with a strict dress code: if you don't wear a jacket and tie you can't eat at all; if you wear it and get an excellent meal, all well and good; if you wear it and get poisoned food, you die and the jacket and tie don't help your corpse. $\endgroup$ Jun 27 '17 at 4:26
  • 1
    $\begingroup$ @dave_thompson_085 Right, I forgot to address this. I've added a quick paragraph on the topic. $\endgroup$
    – Lery
    Jun 27 '17 at 8:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.