def send_message_B(ciphertext, iv): global s_B, A_B, b, p s_B = pow(A_B, b, p) key = hashes.SHA1(util.int_to_bytes(s_B)) key = util.get_ith_block(key, 0, BLOCK_SIZE) plaintext = util.cbc_decrypt(ciphertext, key, iv) assert plaintext == MESSAGE iv = util.random_byte_string(BLOCK_SIZE) return (util.cbc_encrypt(plaintext, key, iv), iv)
def send_message_A(B): global s_A, a, p, B_A B_A = B s_A = pow(B_A, a, p) msg = MESSAGE key = hashes.SHA1(util.int_to_bytes(s_A)) key = util.get_ith_block(key, 0, BLOCK_SIZE) iv = util.random_byte_string(BLOCK_SIZE) return (util.cbc_encrypt(msg, key, iv), iv)
def construct_new_MAC(known_message, MAC, message_suffix, key_length=16): NUM_REGS = 5 original_byte_len = key_length + len(known_message) original_bit_len = original_byte_len * 8 init_regs = [ struct.unpack('>I', util.get_ith_block(MAC, i, 4))[0] for i in range(NUM_REGS) ] glue_padding = b'\x80' + b'\x00' * ( (56 - (original_byte_len + 1) % 64) % 64) + struct.pack( b'>Q', original_bit_len) new_message = known_message + glue_padding + message_suffix return new_message, hashes.SHA1(message_suffix, original_byte_len=key_length + len(new_message), init_state=init_regs)
def verify_message(key, message, MAC): return hashes.SHA1(key + message) == MAC
new_message = known_message + glue_padding + message_suffix return new_message, hashes.SHA1(message_suffix, original_byte_len=key_length + len(new_message), init_state=init_regs) def verify_message(key, message, MAC): return hashes.SHA1(key + message) == MAC if __name__ == '__main__': key = util.random_word().encode('utf-8') known_message = b'comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon' MAC = hashes.SHA1(key + known_message) message_suffix = b';admin=true' for key_length in range(1, 20): new_message, new_MAC = construct_new_MAC(known_message, MAC, message_suffix, key_length=key_length) if verify_message(key, new_message, new_MAC): break print(new_message) print(new_MAC) print(verify_message(key, new_message, new_MAC))
def SHA1_keyed_MAC(key, message): return binascii.hexlify(hashes.SHA1(key + message))
B_B = dh.send_params_B(p, g, A_A) (ciphertext, iv) = dh.send_message_A(B_B) (ciphertext, iv) = dh.send_message_B(ciphertext, iv) print('Successfully executed DH Protocol') # Simulate MITM Attack on DH Protocol # by messing with the 'g' parameter # g = 1 (p, g, A_A) = dh.send_params_A() B_B = dh.send_params_B(p, 1, 1) (ciphertext, iv) = dh.send_message_A(B_B) (_, _) = dh.send_message_B(ciphertext, iv) s = 1 key = hashes.SHA1(util.int_to_bytes(s)) key = util.get_ith_block(key, 0, dh.BLOCK_SIZE) plaintext = util.cbc_decrypt(ciphertext, key, iv) assert plaintext == dh.MESSAGE # g = p (p, g, A_A) = dh.send_params_A() B_B = dh.send_params_B(p, p, 0) (ciphertext, iv) = dh.send_message_A(B_B) (_, _) = dh.send_message_B(ciphertext, iv) s = 0 key = hashes.SHA1(util.int_to_bytes(s)) key = util.get_ith_block(key, 0, dh.BLOCK_SIZE) plaintext = util.cbc_decrypt(ciphertext, key, iv) assert plaintext == dh.MESSAGE