def hmac_sha1(key: bytes, message: bytes): block_size = 64 if len(key) > block_size: key = sha1(key) elif len(key) < block_size: key += b"\x00" * (len(key) - block_size) o_key_pad = bytes([k ^ 0x5C for k in key]) i_key_pad = bytes([k ^ 0x36 for k in key]) return sha1(o_key_pad + sha1(i_key_pad + message))
def diffie_hellman_mitm(): message = b"example message~" print(f"DH'ing message: {message}") # Generate A's DH values. a = randbelow(p) A = pow(g, a, p) print("ACTION: A -> M :: Send `p, g, A`") A = p print("ACTION: M -> B :: Send `p, g, p`") # Generate B's DH values. b = randbelow(p) B = pow(g, b, p) print("ACTION: B -> M :: Send `B`") B = p print("ACTION: M -> A :: Send `p`") # Calculate DH shared key. shared_key_a = sha1(pow(B, a, p).to_bytes(1600, "little"))[:16] # Encrypt message with A's key. iv_a = random_bytes(16) cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_a) message_a = cipher.encrypt(message) print(f"ACTION: A -> M :: Send encrypted message: {message_a}") broken_key = sha1((0).to_bytes(1600, "little"))[:16] cipher = AES.new(broken_key, mode=AES.MODE_CBC, iv=iv_a) broken_message_a = cipher.decrypt(message_a) print(f"ACTION: M :: Decrypted A's message: {broken_message_a}") print(f"ACTION: M -> B :: Relay encrypted message: {message_a}") # Calculate DH shared key. shared_key_b = sha1(pow(A, b, p).to_bytes(1600, "little"))[:16] # Decrypt A's message with shared key. cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_a) decrypted_message_a = cipher.decrypt(message_a) print(f"ACTION: B :: Decrypted A's message: {decrypted_message_a}") iv_b = random_bytes(16) cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_b) message_b = cipher.encrypt(decrypted_message_a) print(f"ACTION: B -> M :: Send A's encrypted message back: {message_b}") cipher = AES.new(broken_key, mode=AES.MODE_CBC, iv=iv_b) broken_message_b = cipher.decrypt(message_b) print(f"ACTION: M :: Decrypted B's message: {broken_message_b}") print(f"ACTION: M -> A :: Relay encrypted message: {message_a}") cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_b) decrypted_message_b = cipher.decrypt(message_b) print(f"ACTION: A :: Decrypted B's message: {decrypted_message_b}") assert broken_message_a == broken_message_b == message
def make_aes_key(integer): return sha1(integer.to_bytes(1600, "little"))[:16]
def diffie_hellman_mitm(g): # Assume p & g have been sent, acknowledged, and tampered with. message = b"example message~" print(f"DH'ing message: {message} with g = {g}") # Generate A's DH values. a = randbelow(p) A = pow(g, a, p) print("ACTION: A -> B :: Send `A`") # Generate B's DH values. b = randbelow(p) B = pow(g, b, p) print("ACTION: B -> A :: Send `B`") # Calculate DH shared key. shared_key_a = make_aes_key(pow(B, a, p)) # Encrypt message with A's key. iv_a = random_bytes(16) cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_a) message_a = cipher.encrypt(message) print(f"ACTION: A -> M :: Send encrypted message: {message_a}") if g == 1: broken_keys = [make_aes_key(1)] elif g == p: broken_keys = [make_aes_key(0)] elif g == p - 1: broken_keys = [make_aes_key(i) for i in [1, p - 1]] ciphers = [AES.new(key, mode=AES.MODE_CBC, iv=iv_a) for key in broken_keys] broken_messages_a = [c.decrypt(message_a) for c in ciphers] print( f"ACTION: M :: Decrypted A's message: {b' or '.join(broken_messages_a)}" ) print(f"ACTION: M -> B :: Relay encrypted message: {message_a}") # Calculate DH shared key. shared_key_b = sha1(pow(A, b, p).to_bytes(1600, "little"))[:16] # Decrypt A's message with shared key. cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_a) decrypted_message_a = cipher.decrypt(message_a) print(f"ACTION: B :: Decrypted A's message: {decrypted_message_a}") iv_b = random_bytes(16) cipher = AES.new(shared_key_b, mode=AES.MODE_CBC, iv=iv_b) message_b = cipher.encrypt(decrypted_message_a) print(f"ACTION: B -> M :: Send A's encrypted message back: {message_b}") ciphers = [AES.new(key, mode=AES.MODE_CBC, iv=iv_b) for key in broken_keys] broken_messages_b = [c.decrypt(message_b) for c in ciphers] print( f"ACTION: M :: Decrypted B's message: {b' or '.join(broken_messages_b)}" ) print(f"ACTION: M -> A :: Relay encrypted message: {message_a}") cipher = AES.new(shared_key_a, mode=AES.MODE_CBC, iv=iv_b) decrypted_message_b = cipher.decrypt(message_b) print(f"ACTION: A :: Decrypted B's message: {decrypted_message_b}") assert message in broken_messages_a assert message in broken_messages_b
int(math.ceil((len(modified_string) - len(admin_str)) / 64)) * 64) modified_hash = (Sha1Hash( digest_vars=(h0, h1, h2, h3, h4), message_byte_len=modified_message_byte_len, ).update(admin_str).digest()) return modified_string, modified_hash if __name__ == "__main__": secret_key = b"luminously" string = (b"comment1=cooking%20MCs;userdata=foo;" b"comment2=%20like%20a%20pound%20of%20bacon") prefix_hash = sha1(string, key=secret_key) modified_string, modified_hash = modify_admin(string, prefix_hash, len(secret_key)) expected_hash = sha1(modified_string, key=secret_key) print("\nModified string:") print(modified_string) print("\nModified hash:") print(modified_hash) print("\nExpected hash:") print(expected_hash) assert modified_hash == expected_hash print("\nPassed")