August 5, 2019

Cryptopals Challenges: #10

In this challenge we are asked to implement AES-CBC.

Cryptopals Challenges: #10

The task of this challenge is to implement an AES-CBC decryption method.  To do that, we should first look at an illustration of how AES-CBC decryption works.

Each ciphertext is decrypted using AES-ECB.  These texts are then XORed against the previous ciphertext bytes.  The first ciphertext is XORed against a special block called an Initialization Vector (IV).  The IV can either be pre-set or randomized when the cipher is initialized.  For this challenge, Cryptopals says to use a key of "YELLOW SUBMARINE" and an IV of "\x00" bytes.

Implementing this decryption uses similar patterns from previous challenges.  First we break the ciphertext into blocks and initialize the IV:

keysize = len(key)
blocks = [ciphertext[i*keysize:(i+1)*keysize] for i in range(int(len(ciphertext)/keysize))]

IV = chr(0).encode() * keysize

Next, for each block we decrypt the block using AES-ECB, XOR these bytes with the previous block, append the plaintext with the decoded string, and record the current block as the last block.

last_block = IV
plaintext = ""

for block in blocks:
	AES_Decrypted = AES_ECB_Decrypt(block, key)
	plaintext += xor_bytes(AES_Decrypted, last_block).decode()	
	last_block = block

Summarized in a function we have:

def AES_CBC_Decrypt(ciphertext, key):
    keysize = len(key)
    blocks = [ciphertext[i*keysize:(i+1)*keysize] for i in range(int(len(ciphertext)/keysize))]

    IV = chr(0).encode() * keysize
    last_block = IV
    plaintext = ""

    for block in blocks:
        AES_Decrypted = AES_ECB_Decrypt(block, key)
        plaintext += xor_bytes(AES_Decrypted, last_block).decode()
        last_block = block

    return plaintext

Loading the file and decrypting with this function gives a similar plaintext from previous challenges of Vanilla Ice lyrics.

Next time we dive into challenge 11, which is a puzzle problem rather than an implementation problem.