def decrypt_aes_cbc_2(text, key, iv): # Create blocks of the key's length each blocks = [text[i:i + len(key)] for i in range(0, len(text), len(key))] results = [] for _, block in enumerate(blocks): # Decrypt the current block with the given key deciphered_block = set1.decrypt_aes_ecb(block, key) # XOR the deciphered block with the IV xored_deciphered_block = set1.XOR(deciphered_block, iv) # Decode the result as a string, and add it to the result set results.extend(xored_deciphered_block) # Set the IV of the next block as the current block's ciphertext iv = block return set2.pkcs7_remove_padding(bytes(results))
def aes_cbc_mode_decrypt(cipher, key, iv): BLOCK_SIZE = len(key) num_blocks = math.ceil(len(cipher) / BLOCK_SIZE) blocks = [] for i in range(num_blocks): blocks.append(cipher[(i*BLOCK_SIZE):(i+1)*BLOCK_SIZE]) output = b'' previous_block = iv for b in blocks[0:]: decrypted_block = set1.fixed_xor(set1.decrypt_aes_ecb(b, key), previous_block) output += decrypted_block previous_block = b # TODO remove padding length :) return output
def challenge_25(): key = set2.random_bytes(16) nonce = random.randrange(1, 10**10) # Get plaintext with open('inputs/25.txt') as file: contents = base64.b64decode(file.read()) plaintext = set2.pkcs7_remove_padding( set1.decrypt_aes_ecb(contents, 'YELLOW SUBMARINE')) # Generate ciphertext ciphertext = set3.encrypt_aes_ctr(plaintext, key, nonce) # Create vulnerable function def vulnerable_ctr_stream_edit_function(ciphertext, offset, newtext): return edit_ctr_stream(ciphertext, key, nonce, offset, newtext) # Find the plaintext using the above function obtained_plaintext = find_ctr_plaintext( ciphertext, vulnerable_ctr_stream_edit_function) # Verify found plaintext matches with the original plaintext assert_true(obtained_plaintext == plaintext)
def get_oracles(): key = random_bytes(16) return lambda x: encrypt_aes_ecb(x, key), lambda x: set1.unpad( set1.decrypt_aes_ecb(x, key))
def encrypt_aes_ecb(text, key, padding=True): from Crypto.Cipher import AES # Create new AES object with the given key in ECB mode obj = AES.new(key, AES.MODE_ECB) if padding: # Compute the padding necessary to make the length of the input text a multiple of len(key) padding = len(key) - len(text) % len(key) # Apply padding text = pkcs7_add_padding(text, len(text) + padding) # Encrypt given text return obj.encrypt(text) assert set1.unpad( set1.decrypt_aes_ecb( encrypt_aes_ecb(bytes("O Brave New World", 'utf-8'), "YELLOW SUBMARINE"), "YELLOW SUBMARINE")) == bytes("O Brave New World", 'utf-8') def decrypt_aes_cbc(text, key, iv, unpad=True): # Create blocks of the key's length each blocks = [text[i:i + len(key)] for i in range(0, len(text), len(key))] results = [] for _, block in enumerate(blocks): # Decrypt the current block with the given key deciphered_block = set1.decrypt_aes_ecb(block, key) # XOR the deciphered block with the IV xored_deciphered_block = set1.XOR(deciphered_block, iv) # Decode the result as a string, and add it to the result set results.extend(xored_deciphered_block) # Set the IV of the next block as the current block's ciphertext
def test_aes_ecb_mode(self): with open('7.txt') as f: contents = bytes(base64.b64decode(f.read())) deciphered = set1.decrypt_aes_ecb(contents, 'YELLOW SUBMARINE') self.assertIn(b"I'm back and I'm ringin' the bell \nA rockin'", deciphered)