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
CBC Ciphertext: 4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81
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 = 1edbf1800618fb28
I believe how this should work is the plaintext for m should be:
$$ m = (c \oplus k) \oplus IV $$
Actually, what my lecture slide says is:
$$ m = D(k, c) \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.