def encrypt_aes_ctr(plaintext, key, nonce): assert len(key) == 16 assert len(nonce) == 8 counter = int(ceil(len(plaintext) / 16)) keystream = [] for i in range(counter): to_encrypt = nonce + int_to_lit_end_bt(i) encrypted_counter = encrypt_aes_128_ecb(to_encrypt, key) keystream.extend(encrypted_counter) keystream = keystream[:len(plaintext)] return xor(plaintext, keystream)
def encryption_oracle_ecb_cbc(bt): key = crypto_random_bytes(16) iv = crypto_random_bytes(16) mode = choice(['ecb', 'cbc']) begin_pad = crypto_random_bytes(random_integer(5, 10)) end_pad = crypto_random_bytes(random_integer(5, 10)) to_encrypt = pad_to_mod_16(begin_pad + bt + end_pad) if mode == 'ecb': ciphertext = encrypt_aes_128_ecb(to_encrypt, key) else: ciphertext = encrypt_aes_cbc(to_encrypt, key, iv) # do not cheat, use mode for validation only return ciphertext, mode
def encrypt_aes_cbc(plaintext, key, iv): assert len(plaintext) % 16 == 0 assert len(key) == 16 assert len(iv) == 16 blocks = chunks_of_bytearray(plaintext, len(key)) initial = iv result = [] for block in blocks: to_encrypt = xor(initial, block) ciphertext_block = encrypt_aes_128_ecb(to_encrypt, key) result.extend(ciphertext_block) initial = ciphertext_block return bytearray(result)
def encryption_oracle_ecb(plaintext): to_encrypt = pad_to_mod_16(padding + plaintext + secret) return encrypt_aes_128_ecb(to_encrypt, oracle_key)
def encrypt_profile_for(email): profile = string_to_bytearray(profile_for(email)) to_encrypt = pad_to_mod_16(profile) return encrypt_aes_128_ecb(to_encrypt, oracle_key)