Help me understand how to do a crypto assignment about AES/CBC

I'm doing the Coursera cryptography I course from Dan Boneh. I am attempting to do week 2's programming assignment, but I think I am having some sort of misunderstanding of either the theory, the actual implementation, or both. I am neither a crypto or python expert so I'm sure I'm messing up both.

Essentially, I am trying to decrypt some ciphertext given the key. Sounds simple. We are given:

In this project you will implement two encryption/decryption systems, one using AES in CBC mode and another using AES in counter mode (CTR). In both cases the 16-byte encryption IV is chosen at random and is prepended to the ciphertext. (I'm just doing CBC first)

CBC key: 140b41b22a29beb4061bda66b6747e14

We're also told: the 16-byte encryption IV is chosen at random and is prepended to the ciphertext.

So I'll go through an example of what I did for the first two blocks. The IV is 16 bit and pre-pended, so it's the first 16 characters of the ciphertext:

IV = 4ca00ff4c898d61e

Next, I tried to decrypt the next block, which is positions 16-31 (0 indexed) of the cipher text:

c[0] = 1edbf1800618fb28

I believe how this should work is the plaintext for m[0] should be:

$$m[0] = (c[0] \oplus k) \oplus IV$$

Actually, what my lecture slide says is:

$$m[0] = D(k, c[0]) \oplus IV$$

And then for the following blocks, just increment the indices by 1: $$m[i] = D(k, c[i]) \oplus c[i-1]$$

But I'm not 100% sure what "D" actually is (yes, decrypt... but is it xoring? Something else?). When I calculated each one in turns, I just got gibberish. If my understanding is correct (the decryption of the current layer being just xoring c[i] with the key), then it could be an implementation problem?

I'm also a bit unsure about xoring the key with the blocks. I know that IV is supposed to be the same length as the blocks (16) but the key is 32 bits. Do I pad or repeat the blocks so they are 32 bits? Do I use the first 16 bits of the key? etc. I have been using this function given by the prof in a previous assignment:

def strxor(a, b):     # xor two strings of different lengths
if len(a) > len(b):
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])


But I don't know if that's still the right way to do it. I know I need to string.decode('hex') before I feed things into the above function and then string.encode('hex') them back into hex afterwards.

• A 128-bit IV would be 32 hex chars, not 16 Dec 29, 2020 at 18:10
• "The IV is 16 bit and pre-pended" No, it's 16 bytes. 32 hex characters. Likewise your blocks are too short, eg the first block is "28a226d160dad07883d04e008a7897ee". Dec 29, 2020 at 18:37
• OK, thanks for the tip. You're right, I had mistaken the length. Fortunately that's easy to change since I automated the block making process... sadly that doesn't appear to be my main issue though. Dec 29, 2020 at 18:50

For the CBC mode the encryption and decryption equations are as follows;

• CBC encryption;

\begin{align} C_1 &= E_k(P_1 \oplus IV)\\ C_i &= E_k(P_i \oplus C_{i-1}),\;\; 1 < i < nb, \end{align}

• CBC decryption;

\begin{align} P_1 =& D_k(C_1) \oplus IV\\ P_i =& D_k(C_i) \oplus C_{i-1},\;\; 1 < i < nb, \end{align}

But I'm not 100% sure what "D" actually is (yes, decrypt... but is it xoring? Something else?).

The $$D$$ is for Encryption and $$E$$ is for encryption, and $$nb$$ is the number of blocks.

If my understanding is correct (the decryption of the current layer being just xoring c[i] with the key), then it could be an implementation problem?

The key is given to AES to produce the encryption and decryptions, we don't x-or with the key, that is OTP or Vigenere.

I'm also a bit unsure about xoring the key with the blocks. I know that IV is supposed to be the same length as the blocks (16) but the key is 32 bits. Do I pad or repeat the blocks so they are 32 bits? Do I use the first 16 bits of the key?

AES has 128-bit block size regardless of the key sized those are 128,192, and 256. Therefore AES can support 128 bit IV/nonces. 128 is 16-bytes and 256 is 32-bytes.

A message to be encrypted with CBC mode needs proper padding like PKCS#7 padding and the padding is performed on the last block. The padding is the missing bytes are filled with the count of the missing bytes, if the last block is full then a new block is needed that is filled with 10. And remember CBC mode is applicable to the padding oracle attack due to improper uses of the padding error and lack of encrypt-then-mac.

The key size must be given to you, and the key size cannot be detected except in the side-channel attacks where if one can see that encryption is 40% slower than AES-128 then it must be AES-128.

• So, am I supposed to just give the key and CT blocks to AES and it spits something out like a black box? That seems a bit against the point of doing an assignment Dec 29, 2020 at 18:36
• Yes, you give the key AES and manage the input and outputs, like on CBC requires chaining and in CTR the increment of the counter and x-or with the ciphertext. Dec 29, 2020 at 18:38
• Let us decrypt the CBC encrypted ciphertext.(IV and Key each of 16 bytes=128 bits)

• key = 140b41b22a29beb4061bda66b6747e14

• IV = 4ca00ff4c898d61e1edbf1800618fb28

• Now if you put them in any CBC decryption function you will get plaintext as

• Basic CBC mode encryption needs padding.

• As Kelalaka mentioned...

• $${P_i=D_k(C_i)\oplus C_{i-1}}$$

• $${C_0 = IV}$$

• Which simply means, when you are decrypting first block, use $${C_0=IV}$$ as a cipher text block,as we don't have any previous encrypted ciphertext block. So, Decrypt the first 16 byte block with Key and then, XOR the decrypted block with IV to get first block of plaintext.

• All subsequent block will use the previous ciphertext block to xor with the CBC decrypted block.