## Python Assignment Help - Solution for CBC Encryption Task

• 19th Jan, 2023
• 16:59 PM

Python Assignment Help - Solution for CBC Encryption Task

#, ,
#Python 3.6

import Crypto.Cipher.AES as AES

def xor(a, b):
my_result = bytearray()
for a, b in zip(a, b):
xor = a ^ b
my_result.append(xor)
return my_result

def get_xor(a, b):
xor = ""
for x,y in zip(a,b):
xor += str(int(x) ^ int(y))
return xor

def find_flipped_block(my_blocks, n):
for i in range(1, n+1):
for j in range(1, 16):
right = my_blocks[n-i][0]
left = my_blocks[n-i][j]
test = right ^ left
if test != 0:
return n-i

def get_common_byte(block):
for i in range(0, 16):
if block[i] == block[i+1]:
return block[i]
else:
if block[i] == block[i+2]:
return block[i]
else:
return block[i+1]

def cbc_custom_decrypt(k, n, cipher):
if n <= 0:
return
my_blocks = []
crypto = AES.new(k, AES.MODE_ECB)
my_blocks.append(cipher[16:32])
my_decryption = []
if n > 1:
for i in range(2, n + 1):
index = 16 * i
my_blocks.append(cipher[index: index + 16])
blocks_number = len(my_blocks)
for j in range(1, blocks_number):
decryption = crypto.decrypt(my_blocks[blocks_number - j])
one_slice = xor(decryption, my_blocks[blocks_number - j - 1])
my_decryption.append(one_slice)
last_decryption = crypto.decrypt(my_blocks[0])
first_slice = xor(last_decryption, cipher[:16])
my_decryption.append(first_slice)
my_length = len(my_decryption)
for k in range(2, my_length + 1):
first_slice.extend(my_decryption[my_length - k])
return bytes(first_slice)

def cbc_flip_fix(k, n, cipher):
my_flipped_plaintext = cbc_custom_decrypt(k, n, cipher)
my_blocks = []
byte_index = 0
for i in range(0, n):
index = 16 * i
my_blocks.append(my_flipped_plaintext[index: index + 16])
flipped_block_num = find_flipped_block(my_blocks, n)
common = get_common_byte(my_blocks[flipped_block_num])
for j in range(1, 16):
if my_blocks[flipped_block_num][0] == common:
if my_blocks[flipped_block_num][0] != my_blocks[flipped_block_num][j]:
byte_index = j
else:
byte_index = 0
err = my_blocks[flipped_block_num][byte_index]
err = "{:08b}".format(err)
common = "{:08b}".format(common)
test_xor = get_xor(common, err)
cipher_index = 16 * (flipped_block_num-1) + 16
flipped_cipher_block = cipher[cipher_index:cipher_index+17]
flipped_cipher_byte = "{:08b}".format(flipped_cipher_block[byte_index])
new_cipher_byte = bytes([int(get_xor(test_xor, flipped_cipher_byte), 2)])
new_cipher = cipher[:cipher_index + byte_index] + new_cipher_byte + cipher[cipher_index + byte_index + 1:]
block_plain_index = 16 * (flipped_block_num - 1)
my_temp = cbc_custom_decrypt(k, n, new_cipher)
return my_temp[block_plain_index : block_plain_index + 16]

if __name__ == "__main__":
k = b'\x81\x0ff\t\x04\xb6\xcf\x1f.\x10\x8frd\xb4E\x19'
print("type(k) = {}".format(type(k)))
print("k.hex() = {}".format(k.hex()))
IV = b'e|\x92\xd0\x8b\xd9\x00\xc8X\xf2Noi\xa1\x155'
print("len(IV) = {}".format(len(IV)))
cipher = b'e|\x92\xd0\x8b\xd9\x00\xc8X\xf2Noi\xa1\x155\xb5b\xe7r\xb1\xec\xb5\xed\xca\xca\x1f\$\xf8\xe33%'
print("type(cipher) = {}".format(type(cipher)))
print("len(cipher) = {}".format(len(cipher)))
print("Question 1:")
print("N = 1")
output = cbc_custom_decrypt(k, 1, cipher)
print("\ttype(output) = {}".format(type(output)))
print("\toutput = {}".format(output))
print("N = 2")
output = cbc_custom_decrypt(k, 2, cipher)
print("\ttype(output) = {}".format(type(output)))
print("\toutput = {}".format(output))
print("Test more:")
k = b'\x81\x0ff\t\x04\xb6\xcf\x1f.\x10\x8frd\xb4E\x19'
n = 1
cipher = b'e|\x92\xd0\x8b\xd9\x00\xc8X\xf2Noi\xa1\x155\x8b\xa5\xb7\xdcka\xaa\x94=a_!x\x1a\xcf\xf4'
output = cbc_custom_decrypt(k, n, cipher)
print("\ttype(output) = {}".format(type(output)))
print("\toutput = {}".format(output))
print("Question 2:")
print("N = 1")
cipher = b'e|\x92\xd0\x8b\xd9\x00\xc8X\xf2Noi\xa1\x155\xb5b\xe7r\xb1\xec\xb5\xed\xca\xca\x1f\$\xf8\xe33%'
output = cbc_flip_fix(k, 1, cipher)
print("\ttype(output) = {}".format(type(output)))
print("\toutput = {}".format(output))