def test_single_byte_xor_cryptanalysis_many(): """Tests ability to break single character xor for several plaintexts encrypted with every possible byte""" plaintexts = [b'The optional source parameter can be used to initialize the array', b'The quick brown fox jumps over the lazy dog', b'My mind is the place where I make my plans', b'The world is the place where I take my stand'] for pt in plaintexts: i = random.choice(range(255)) key_byte = bytes([i]) ct = set1.fixed_xor(pt, key_byte * len(pt)) assert set1.single_byte_xor_cryptanalysis(ct)[:2] == (pt, ord(key_byte))
def test_single_byte_xor_cryptanalysis_many(): """Tests ability to break single character xor for several plaintexts encrypted with every possible byte""" plaintexts = [ b'The optional source parameter can be used to initialize the array', b'The quick brown fox jumps over the lazy dog', b'My mind is the place where I make my plans', b'The world is the place where I take my stand' ] for pt in plaintexts: i = random.choice(range(255)) key_byte = bytes([i]) ct = set1.fixed_xor(pt, key_byte * len(pt)) assert set1.single_byte_xor_cryptanalysis(ct)[:2] == (pt, ord(key_byte))
def encrypt_aes_cbc_mode(plaintext, key, iv): """Encrypt plaintext with AES in CBC mode, using provided key and iv (initialization vector) """ assert len(key) == len(iv), "Key and initialization vector must be same length" pt_blocks = bytes_to_padded_blocks(plaintext, len(key)) ciphertext = b'' xor_with = iv # Initially, we XOR plaintext with IV # For each block, xor plaintext with xor_with, then encrypt and append to ciphertext. # Each successive plaintext block is XORed with the previous ciphertext block before encryption. for pt_block in pt_blocks: new_ct_block = set1.encrypt_aes_ecb_mode(set1.fixed_xor(pt_block, xor_with), key) ciphertext = ciphertext + new_ct_block xor_with = new_ct_block return ciphertext
def decrypt_aes_cbc_mode(ciphertext, key, iv): """Challenge 10 Decrypt plaintext with AES in CBC mode, using provided key and iv (initialization vector) """ assert len(key) == len(iv), "Key and initialization vector must be same length" ct_blocks = bytes_to_padded_blocks(ciphertext, len(key)) plaintext = b'' xor_with = iv # Initially, we XOR decrypted ciphertext with IV # For each block, decrypt ciphertext, then XOR with xor_with, and append to plaintext. # After decryption, each successive decrypted block is XORed with the previous ciphertext block. for ct_block in ct_blocks: new_pt_block = set1.fixed_xor(xor_with, set1.decrypt_aes_ecb_mode(ct_block, key)) plaintext = plaintext + new_pt_block xor_with = ct_block return plaintext
def encrypt_aes_cbc_mode(plaintext, key, iv): """Encrypt plaintext with AES in CBC mode, using provided key and iv (initialization vector) """ assert len(key) == len( iv), "Key and initialization vector must be same length" pt_blocks = bytes_to_padded_blocks(plaintext, len(key)) ciphertext = b'' xor_with = iv # Initially, we XOR plaintext with IV # For each block, xor plaintext with xor_with, then encrypt and append to ciphertext. # Each successive plaintext block is XORed with the previous ciphertext block before encryption. for pt_block in pt_blocks: new_ct_block = set1.encrypt_aes_ecb_mode( set1.fixed_xor(pt_block, xor_with), key) ciphertext = ciphertext + new_ct_block xor_with = new_ct_block return ciphertext
def aes_cbc_mode_encrypt(text, key, iv): BLOCK_SIZE = len(key) num_blocks = math.ceil(len(text) / BLOCK_SIZE) blocks = [] for i in range(num_blocks): blocks.append( text[(i*BLOCK_SIZE):(i+1)*BLOCK_SIZE] ) output = b'' previous_block = iv for b in blocks: encrypted_block = set1.encrypt_aes_ecb(set1.fixed_xor(previous_block, b), key) output += encrypted_block previous_block = encrypted_block return output
def aes_cbc_decrypt(cipher_blob, aes_key, iv=None): '''decrypts ciphertext according to AES protocol in CBC mode''' if iv is None: iv = b'\x00' * 16 plaintext = b'' cipher_blocks = [ cipher_blob[i:i + 16] for i in range(0, len(cipher_blob), 16) ] assert len(cipher_blocks[-1]) == 16 to_xor = iv for block in cipher_blocks: deciphered = aes_ecb_decrypt(block, aes_key) plaintext += fixed_xor(to_xor, deciphered) to_xor = block return plaintext
def decrypt_aes_cbc_mode(ciphertext, key, iv): """Challenge 10 Decrypt plaintext with AES in CBC mode, using provided key and iv (initialization vector) """ assert len(key) == len( iv), "Key and initialization vector must be same length" ct_blocks = bytes_to_padded_blocks(ciphertext, len(key)) plaintext = b'' xor_with = iv # Initially, we XOR decrypted ciphertext with IV # For each block, decrypt ciphertext, then XOR with xor_with, and append to plaintext. # After decryption, each successive decrypted block is XORed with the previous ciphertext block. for ct_block in ct_blocks: new_pt_block = set1.fixed_xor(xor_with, set1.decrypt_aes_ecb_mode(ct_block, key)) plaintext = plaintext + new_pt_block xor_with = ct_block return plaintext
def aes_cbc_encrypt(plaintext_blob, aes_key, iv=None): '''encrypts plaintext according to AES protocol in CBC mode''' if iv is None: iv = b'\x00' * 16 ciphertext = b'' plaintext_blob = pkcs7(plaintext_blob) plaintext_blocks = [ plaintext_blob[i:i + 16] for i in range(0, len(plaintext_blob), 16) ] to_xor = iv for block in plaintext_blocks: xored = fixed_xor(to_xor, block) encrypted = aes_ecb_encrypt(xored, aes_key) ciphertext += encrypted to_xor = encrypted return ciphertext
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 test_fixed_xor_returns_correct_amount(): """Returns correct XOR'd value.""" assert fixed_xor(HEX2, HEX3) == HEX_RESULT1
def test_fixed_xor_raises_error_if_buffer_lengths_not_equal(): """Unequal buffer lengths not equal length raises error.""" with pytest.raises(ValueError): fixed_xor(HEX1, HEX2)
def test_fixed_xor_accepts_two_buffers(): """Accept text if incoming is hexidecimal.""" assert fixed_xor(HEX2, HEX3)
def test_fixed_xor(): input_1 = binascii.unhexlify(b'1c0111001f010100061a024b53535009181c') input_2 = binascii.unhexlify(b'686974207468652062756c6c277320657965') expected_output = binascii.unhexlify(b'746865206b696420646f6e277420706c6179') assert set1.fixed_xor(input_1, input_2) == expected_output
def test_fixed_xor(): input_1 = binascii.unhexlify(b'1c0111001f010100061a024b53535009181c') input_2 = binascii.unhexlify(b'686974207468652062756c6c277320657965') expected_output = binascii.unhexlify( b'746865206b696420646f6e277420706c6179') assert set1.fixed_xor(input_1, input_2) == expected_output
def test_fixed_xor(self): a = "0x1c0111001f010100061a024b53535009181c" b = "0x686974207468652062756c6c277320657965" c = "0x746865206b696420646f6e277420706c6179" self.assertEqual(set1.fixed_xor(a, b), c)
def test_fixed_xor(self): self.assertEqual( "746865206b696420646f6e277420706c6179", fixed_xor("1c0111001f010100061a024b53535009181c", "686974207468652062756c6c277320657965"))
def test_fixed_xor(self): self.assertEqual(set1.fixed_xor(bytes.fromhex("1c0111001f010100061a024b53535009181c"), bytes.fromhex("686974207468652062756c6c277320657965")), bytes.fromhex("746865206b696420646f6e277420706c6179"))