def brute_force_ecb_padding(plaintext, block_size, oracle): """Helper function to brute force the PKCS7 padding for the ECB break :param plaintext: The current plaintext guess :param block_size: The block size of the oracle :param oracle: ECB encryption oracle that encrypts AES-128-ECB(your-string || unknown-string, random-key) :return: The correct unknown-string or None on failure to match """ last_block_start = round_down(len(plaintext), block_size) expected_ciphertext = oracle('') # The plaintext may have padding bytes in it so try padding all slices of the last block # When the encryption of the plaintext + padding matches the encryption of an empty string we know the plaintext # is correct for i in xrange(last_block_start, len(plaintext)): plaintext_guess = plaintext[:i] # Now pad it manually since the hidden string will be appended plaintext_guess_w_padding = pkcs7_pad(plaintext_guess, block_size) guess_ciphertext = oracle(plaintext_guess_w_padding)[:len(expected_ciphertext)] if guess_ciphertext == expected_ciphertext: return plaintext_guess return None
def test_pkcs7_pad(): """ Set 2, Challenge 9 """ assert pkcs7_pad('YELLOW SUBMARINE', 20) == 'YELLOW SUBMARINE\x04\x04\x04\x04'