def pcbc_bitflipping(): print('---------- PCBC ----------') plaintext = 'From:Lucas\nTo:Pedro\nContent:the PCBC mode of encryption is NOT vulnerable to bit flipping' print('Original plaintext:', plaintext, sep='\n', end='\n\n') ciphertext = cbc.encrypt(plaintext, KEY) ##### modifying the IV to bitflip the first block ##### iv = bytearray(ciphertext[:pcbc.IV_SIZE]) iv[5:] = common.xor(iv[5:], common.xor(b'Lucas', b'Mario')) ciphertext = bytes(iv) + ciphertext[pcbc.IV_SIZE:] ####################################################### print('Bitflipping Lucas to Mario...') plaintext = pcbc.decrypt(ciphertext, KEY) print('Decrypted ciphertext:', plaintext, sep='\n', end="\n\n") print('List of bytes of the plaintext:', list(bytes(plaintext, 'utf-8')), sep='\n', end="\n\n") ##### modifying the second block ##### block = bytearray(ciphertext[pcbc.BLOCK_SIZE:pcbc.BLOCK_SIZE * 2]) block[4:9] = common.xor(block[4:9], common.xor(b'Pedro', b'Mario')) ciphertext = ciphertext[:pcbc. BLOCK_SIZE] + block + ciphertext[pcbc.BLOCK_SIZE * 2:] ###################################### print('Bitflipping Pedro to Mario...') plaintext = pcbc.decrypt(ciphertext, KEY) print('Decrypted ciphertext:', plaintext, end="\n\n")
def encrypt_block(self, plaintext, ciphertext_blocks): if self.verbose: print("[+] encrypting block {}".format(plaintext)) ivs = [b'\x41' * self.block_size] + ciphertext_blocks[:-1] print("ivs: {}".format(ivs)) decrypted = self.decrypt_block(b''.join(ivs), ciphertext_blocks[-1]) ivs[0] = xor(xor(plaintext, decrypted), ivs[0]) return ivs[0]
def s2v(key, ad_list, block_size=16): """ SIV mode s2v integrity and iv generation ad_list is a list of strings that are included in the integrity check """ if len(ad_list) == 0: return aes_cmac(key, (block_size-1)*"\00"+"\01") d = aes_cmac(key, block_size*"\00") for i in range( len(ad_list)-1 ): d = xor( dbl(d), aes_cmac(key, ad_list[i]) ) if len( ad_list[-1] ) >= block_size: # last item t = ad_list[-1][:-block_size] + xor( ad_list[-1][-block_size:], d) # xorend else: t = xor( dbl(d), pad(ad_list[-1]) ) return aes_cmac(key, t)
def s2v(key, ad_list, block_size=16): """ SIV mode s2v integrity and iv generation ad_list is a list of strings that are included in the integrity check """ if len(ad_list) == 0: return aes_cmac(key, (block_size - 1) * "\00" + "\01") d = aes_cmac(key, block_size * "\00") for i in range(len(ad_list) - 1): d = xor(dbl(d), aes_cmac(key, ad_list[i])) if len(ad_list[-1]) >= block_size: # last item t = ad_list[-1][:-block_size] + xor(ad_list[-1][-block_size:], d) # xorend else: t = xor(dbl(d), pad(ad_list[-1])) return aes_cmac(key, t)
def pcbc_decryption(blocks: Iterator, keys: list) -> Union[str, bytes]: next_iv = next(blocks) plaintext = bytes() for block in blocks: plainblock = common.decrypt_block(block, keys, next_iv) next_iv = common.xor(block, plainblock) plaintext += plainblock return plaintext
def pcbc_encryption(blocks: Iterator, keys: list) -> bytes: ciphertext = iv next_iv = iv for block in blocks: cipherblock = common.encrypt_block(block, keys, next_iv) next_iv = common.xor(block, cipherblock) ciphertext += cipherblock return ciphertext
def ecb_bitflipping(): print('---------- ECB ----------') plaintext = 'From:Lucas\nTo:Pedro\nContent:the ECB mode of encryption is predictable' print('Original plaintext:', plaintext, sep='\n', end='\n\n') ciphertext = ecb.encrypt(plaintext, KEY) ##### here I try to modify the second block - change Pedro to Mario ##### block = bytearray(ciphertext[ecb.BLOCK_SIZE:ecb.BLOCK_SIZE * 2]) block[4:9] = common.xor(block[4:9], common.xor(b'Pedro', b'Mario')) ciphertext = ciphertext[:ecb. BLOCK_SIZE] + block + ciphertext[ecb.BLOCK_SIZE * 2:] ################################################# print('Bitflipping Pedro to Mario...') plaintext = ecb.decrypt(ciphertext, KEY) print('Decrypted ciphertext:', plaintext, sep='\n', end="\n\n")
def main(argv): cypher_texts = [common.hex_to_ascii(cypher_text) for cypher_text in files.read_lines(argv[0])] key = encdec.many_time_pad_crack(cypher_texts, len(cypher_texts[10])) plain_text = common.string_to_ascii('The secret message is: When using a stream cipher, never use the key more than once') new_key = common.xor(plain_text, cypher_texts[10]) print print 'Decrypt Many-time Pad Demo' print for i in xrange(len(cypher_texts)): print 'Message %2d = %s' % ((i + 1), common.ascii_to_string(common.xor(cypher_texts[i], key))) print print 'Make best guess and use to derive key' print for i in xrange(len(cypher_texts)): print 'Message %2d = %s' % ((i + 1), common.ascii_to_string(common.xor(cypher_texts[i], new_key))) print
def siv_encrypt(key, pt, ad_list): """ """ blksize=16 # AES block size keysize = len(key)/2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key ad = ad_list + [pt] iv = s2v(key1, ad ) q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL # clear 32nd and 64th bits m = (len(pt)+blksize-1)/blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt( int_to_string(q+i, padto=blksize) ) x = x[0:len(pt)] # trim x to leftmost to match plain text which may not be block aligned ct = xor(pt,x) return iv + ct # concatenate initialization vector and cipher text
def siv_encrypt(key, pt, ad_list): """ """ blksize = 16 # AES block size keysize = len( key) / 2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key ad = ad_list + [pt] iv = s2v(key1, ad) q = string_to_int( iv) & 0xffffffffffffffff7fffffff7fffffffL # clear 32nd and 64th bits m = (len(pt) + blksize - 1) / blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt(int_to_string(q + i, padto=blksize)) x = x[0:len( pt )] # trim x to leftmost to match plain text which may not be block aligned ct = xor(pt, x) return iv + ct # concatenate initialization vector and cipher text
def siv_decrypt(key, encrypted_string, ad_list): """ """ blksize = 16 # AES block size iv = encrypted_string[:16] # leftmost 128 bits (16 octets) ct = encrypted_string[16:] keysize = len(key)/2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL m = (len(ct)+blksize-1)/blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt( int_to_string(q+i, padto=blksize) ) x = x = x[0:len(ct)] pt = xor(ct,x) ad = ad_list + [pt] t = s2v( key1, ad ) if t == iv: return pt else: raise 'SIV Integrity Check Error'
def siv_decrypt(key, encrypted_string, ad_list): """ """ blksize = 16 # AES block size iv = encrypted_string[:16] # leftmost 128 bits (16 octets) ct = encrypted_string[16:] keysize = len( key) / 2 # SIV key is two keys of equal size for CMAC and CTR key1 = key[0:keysize] # leftmost half of key key2 = key[-keysize:] # rightmost half of key q = string_to_int(iv) & 0xffffffffffffffff7fffffff7fffffffL m = (len(ct) + blksize - 1) / blksize x = '' aes = AES.new(key2, AES.MODE_ECB) for i in range(m): x = x + aes.encrypt(int_to_string(q + i, padto=blksize)) x = x = x[0:len(ct)] pt = xor(ct, x) ad = ad_list + [pt] t = s2v(key1, ad) if t == iv: return pt else: raise 'SIV Integrity Check Error'