def aes_ctr_decrypt(ciphertext, key, nonce_generator): plaintext = '' for ct_block in chunks(ciphertext, 16): nonce = nonce_generator.next() key_steam = aes_ecb_encrypt(nonce, key) plaintext += string_xor(ct_block, key_steam) return plaintext
def aes_ctr_encrypt(plaintext, key, nonce_generator): ciphertext = '' for pt_block in chunks(plaintext, 16): nonce = nonce_generator.next() key_steam = aes_ecb_encrypt(nonce, key) ciphertext += string_xor(pt_block, key_steam) return ciphertext
def break_repeating_nonce_ctr(ciphertexts): """ Decrypt CTR encrypted ciphertexts that were encrypted with a fixed nonce :param ciphertextx: A list of ciphertexts encrypted with a fixed nonce :return: A list of decrypted plaintexts """ block_size = 16 ciphertext = ''.join(ct[:block_size] for ct in ciphertexts) guess = list(chunks(break_repeating_key_xor(ciphertext, keysize=block_size), block_size)) block_keystream = string_xor(guess[0], ciphertexts[0]) plaintexts = [] for ct in ciphertexts: plaintext = '' for block in chunks(ct, block_size): plaintext += string_xor(block, block_keystream) plaintexts.append(plaintext) return plaintexts
def aes_cbc_decrypt(ciphertext, key, iv): """ Perform AES CBC decryption This is the solution to Set 2, Challenge 10 :param ciphertext: The data to or decrypt :param key: The AES key to use :param iv: The initialization vector :return: The resulting plaintext """ xor_block = iv plaintext = '' for ct_block in chunks(ciphertext, 16): plaintext += string_xor(aes_ecb_decrypt(ct_block, key), xor_block) xor_block = ct_block return plaintext
def aes_cbc_encrypt(plaintext, key, iv=None): """ Perform AES CBC encryption, adding PKCS 7 padding as needed :param plaintext: The data to encrypt :param key: The AES key to use :param iv: The initialization vector :return: The resulting ciphertext """ iv = os.urandom(16) if iv is None else iv xor_block = iv ciphertext = '' for pt_block in chunks(plaintext, 16): ct_block = aes_ecb_encrypt(string_xor(pt_block, xor_block), key) ciphertext += ct_block xor_block = ct_block return ciphertext, iv
def cbc_padding_attack_block(ct1, ct2, padding_valid_fn): # In = Cn-1 ^ Pn -> Pn = In ^ Cn-1 I = '' block_size = 16 for num_padding_bytes in xrange(1, block_size+1): pad_xor = ''.join(chr(num_padding_bytes ^ ord(i_byte)) for i_byte in I) for i in xrange(256): c_p = '\x00' * (block_size-num_padding_bytes) + chr(i) + pad_xor if padding_valid_fn(ct2, c_p): I = chr(i ^ num_padding_bytes) + I break pt = string_xor(ct1, I) return pt
def test_string_xor(): assert cc_util.string_xor('\x0A\x0B\x0C\x0D', 'abcd') == 'kioi'