diff --git a/client_test_2.py b/client_test_2.py new file mode 100644 index 0000000..35008b8 --- /dev/null +++ b/client_test_2.py @@ -0,0 +1,37 @@ +import socket +import sys +from utils.send_receive import * + +# Create a TCP/IP socket +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +# Connect the socket to the port where the server is listening +server_address = ('localhost', 15555) +print('connecting to {} port {}'.format(*server_address)) +sock.connect(server_address) + +try: + + # Send data + message = b'This is the message. It will be repeated.' + print('sending {!r}'.format(message)) + send_msg(sock, message) + #sock.sendall(message) + quit_msg_code = b'|<--eos-->|' + + # Look for the response + #amount_received = 0 + #amount_expected = len(message) + + while data != quit_msg_code: + #while 1: + #data = sock.recv(16) + #amount_received += len(data) + #print('received {!r}'.format(data)) + data = recv_msg(sock) + print('will send \'eos\' signal') + sock.sendall(quit_msg_code) + +finally: + print('closing socket') + sock.close() diff --git a/client_test_3.py b/client_test_3.py new file mode 100644 index 0000000..4c22173 --- /dev/null +++ b/client_test_3.py @@ -0,0 +1,48 @@ +# Python TCP Client A +import socket + +# Basic cryptography tools +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa + +# To format created key obj into text to be used/exported +from cryptography.hazmat.primitives import serialization + +# Home made RSA Utils +from utils.rsa_tenamortech_utils import * +from utils.client_keys_manager import * + +host = socket.gethostname() +port = 2004 +BUFFER_SIZE = 2000 +#MESSAGE = input("tcpClientA: Enter message/ Enter exit:").encode('utf-8') +MESSAGE = "" +tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +tcpClientA.connect((host, port)) +got_pub_key_server = False + +(private_key,public_key) = check_for_existing_keys() +public_key_pem = public_key_serializer(public_key) + +def de_serialize_pub_key(public_key_pem): + return serialization.load_pem_public_key(public_key_pem,backend=default_backend()) + +while MESSAGE != 'exit': + data = tcpClientA.recv(BUFFER_SIZE) + if not got_pub_key_server: + public_key_server = de_serialize_pub_key(data) + got_pub_key_server = True + # Now we have the pub key of the server, we will send our pub key too + #encrypted_public_key = encrypt_msg(public_key_pem, public_key_server) + encrypted_public_key = encrypt_msg(bytes("test123456789000000000000000000000000000iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii000", 'utf-8'), public_key_server) + print("Server public key received") + print("Sending current client public key [ ... ] ") + tcpClientA.send(encrypted_public_key) + print("Sending current client public key [ OK ] ") + + else: + print(" Client2 received data:", data) + MESSAGE = input("tcpClientA: Enter message to continue/ Enter exit:").encode('utf-8') + tcpClientA.send(MESSAGE) + +tcpClientA.close() diff --git a/server_test_2.py b/server_test_2.py new file mode 100644 index 0000000..9e6f5ce --- /dev/null +++ b/server_test_2.py @@ -0,0 +1,30 @@ +import asyncio, socket +from utils.keys_manager_1 import * +from utils.send_receive import * + + +async def handle_client(reader, writer): + request = None + quit_msg_code = b'|<--eos-->|' + (private_key,public_key) = check_for_existing_keys() + while request != quit_msg_code: + print('Receiving ans [ ... ]') + request = recv_msg(reader) + #request = (await reader.read(255)).decode('utf8') + print('Receiving ans [ OK ] {}'.format(request)) + response = str(request) + '\n' + send_msg_async(writer, response) + #writer.write(response.encode('utf8')) + try: + await writer.drain() + # Prevent closed connections without 'eos' + except ConnectionResetError: + print('Connection Closed') + break + print('Received \'eos\' signal, will now close session [ ... ]') + writer.close() + print('Session closed [ OK ]') + +loop = asyncio.get_event_loop() +loop.create_task(asyncio.start_server(handle_client, 'localhost', 15555)) +loop.run_forever() diff --git a/server_test_3.py b/server_test_3.py new file mode 100644 index 0000000..864de72 --- /dev/null +++ b/server_test_3.py @@ -0,0 +1,53 @@ +import socket +from threading import Thread +from socketserver import ThreadingMixIn +from utils.keys_manager_1 import * + +# --- Init keys --- +() + +# Multithreaded Python server : TCP Server Socket Thread Pool +class ClientThread(Thread): + + def __init__(self,ip,port, private_key, public_key): + Thread.__init__(self) + self.ip = ip + self.port = port + #print(public_key_serializer(public_key)) + print("[+] New server socket thread started for " + str(ip) + ":" + str(port)) + public_key_pem = public_key_serializer(public_key) + conn.send(public_key_pem) + + def run(self): + while True : + data = conn.recv(2048) + print("Server received data:", data) + MESSAGE = input("Multithreaded Python server : Enter Response from Server/Enter exit:").encode('utf-8') + if MESSAGE == 'exit': + break + conn.send(MESSAGE) # echo + +# Multithreaded Python server : TCP Server Socket Program Stub +TCP_IP = '0.0.0.0' +TCP_PORT = 2004 +BUFFER_SIZE = 20 # Usually 1024, but we need quick response + +tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +tcpServer.bind((TCP_IP, TCP_PORT)) +threads = [] + +# --- Init keys --- +(private_key, public_key) = check_for_existing_keys() +print(public_key_serializer(public_key)) + +while True: + tcpServer.listen(4) + print("Multithreaded Python server : Waiting for connections from TCP clients...") + (conn, (ip,port)) = tcpServer.accept() + newthread = ClientThread(ip,port,private_key,public_key) + newthread.start() + threads.append(newthread) + +for t in threads: + t.join() diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/__pycache__/__init__.cpython-36.pyc b/utils/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..e6e4fcc Binary files /dev/null and b/utils/__pycache__/__init__.cpython-36.pyc differ diff --git a/utils/__pycache__/client_keys_manager.cpython-36.pyc b/utils/__pycache__/client_keys_manager.cpython-36.pyc new file mode 100644 index 0000000..c58fb0c Binary files /dev/null and b/utils/__pycache__/client_keys_manager.cpython-36.pyc differ diff --git a/utils/__pycache__/keys_manager_1.cpython-36.pyc b/utils/__pycache__/keys_manager_1.cpython-36.pyc new file mode 100644 index 0000000..88cf825 Binary files /dev/null and b/utils/__pycache__/keys_manager_1.cpython-36.pyc differ diff --git a/utils/__pycache__/rsa_tenamortech_utils.cpython-36.pyc b/utils/__pycache__/rsa_tenamortech_utils.cpython-36.pyc new file mode 100644 index 0000000..1c998da Binary files /dev/null and b/utils/__pycache__/rsa_tenamortech_utils.cpython-36.pyc differ diff --git a/utils/client_keys_manager.py b/utils/client_keys_manager.py new file mode 100644 index 0000000..c89779d --- /dev/null +++ b/utils/client_keys_manager.py @@ -0,0 +1,75 @@ +#=========================================================================================== +# _____ _____ _ _ _ __ __ ___ ____ _____ _____ ____ _ _ +# |_ _| ____| \ | | / \ | \/ |/ _ \| _ \_ _| ____/ ___| | | | +# | | | _| | \| | / _ \ | |\/| | | | | |_) || | | _|| | | |_| | +# | | | |___| |\ |/ ___ \| | | | |_| | _ < | | | |__| |___| _ | +# |_| |_____|_| \_/_/ \_\_| |_|\___/|_| \_\|_| |_____\____|_| |_| +# +# RSA Client Keys Manager V1 (Python 3.6) +# +# Sources: +# https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/ +# https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python +# https://stackoverflow.com/questions/273192/how-can-i-safely-create-a-nested-directory +# +#=========================================================================================== + +# Basic cryptography tools +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa + +# To format created key obj into text to be used/exported +from cryptography.hazmat.primitives import serialization + +# To get user home directory +from pathlib import Path + +# Home made RSA Keys lib +from utils.rsa_tenamortech_utils import * + +def check_for_existing_keys(): + keys_dir_path = Path.home() / '.auth_server_test' / 'client' + private_key_path = keys_dir_path / 'id_rsa' + public_key_path = keys_dir_path / 'id_rsa.pub' + + # ========================================================= + # Private key file exists ? Load it + # --- Public key file exists ? Load it + # --- No Public key file ? Generate it from the Private + # No Private key file ? Generate both keys (save as well) + # ========================================================= + + if(private_key_path.exists()): + print('Find private key from file [ OK ]') + # Load private key from file + print('Load private key from file [ ... ]') + with open(str(private_key_path), "rb") as key_file: + private_key = serialization.load_pem_private_key( + key_file.read(), + password=None, + backend=default_backend() + ) + print('Load private key from file [ OK ]') + if(public_key_path.exists()): + print('Find public key from file [ OK ]') + # Load public key from file + print('Load public key from file [ ... ]') + with open(str(public_key_path), "rb") as key_file: + public_key = serialization.load_pem_public_key( + key_file.read(), + backend=default_backend() + ) + print('Load public key from file [ OK ]') + # Return keys + return (private_key,public_key) + else: + print('Find public key from file [ FAIL ]') + print('Generating public key from private key [ ... ]') + public_key = generate_public_key(1,private_key) + print('Generating public key from private key [ OK ]') + return (private_key,public_key) + else: + print('Find private key from file [ FAIL ]') + print('New keys will be generated') + return generate_keys(1) +check_for_existing_keys() diff --git a/utils/keys_manager_1.py b/utils/keys_manager_1.py new file mode 100644 index 0000000..419a6de --- /dev/null +++ b/utils/keys_manager_1.py @@ -0,0 +1,137 @@ +#=========================================================================================== +# _____ _____ _ _ _ __ __ ___ ____ _____ _____ ____ _ _ +# |_ _| ____| \ | | / \ | \/ |/ _ \| _ \_ _| ____/ ___| | | | +# | | | _| | \| | / _ \ | |\/| | | | | |_) || | | _|| | | |_| | +# | | | |___| |\ |/ ___ \| | | | |_| | _ < | | | |__| |___| _ | +# |_| |_____|_| \_/_/ \_\_| |_|\___/|_| \_\|_| |_____\____|_| |_| +# +# RSA Keys Manager V1 (Python 3.6) +# +# Sources: +# https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/ +# https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python +# https://stackoverflow.com/questions/273192/how-can-i-safely-create-a-nested-directory +# +#=========================================================================================== + +# Basic cryptography tools +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa + +# To format created key obj into text to be used/exported +from cryptography.hazmat.primitives import serialization + +# To get user home directory +from pathlib import Path + + +def generate_private_key(): + # Generate Private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + backend=default_backend() + ) + save_key(private_key, 0) + return private_key + + +def generate_public_key(private_key): + # Get Public key from Private + public_key = private_key.public_key() + save_key(public_key, 1) + return public_key + + +def private_key_serializer(private_key): + # Key serialization + private_key_pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + return private_key_pem + + +def public_key_serializer(public_key): + # Key serialization + public_key_pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + #print(public_key_pem) + return public_key_pem + + +def save_key(key, key_type): + keys_dir_path = Path.home() / '.auth_server_test' + # Path exists ? If not we will create it + keys_dir_path.mkdir(exist_ok=True) + if(key_type == 0): + key_pem = private_key_serializer(key) + key_path = keys_dir_path / 'id_rsa' + elif(key_type == 1): + key_pem = public_key_serializer(key) + key_path = keys_dir_path / 'id_rsa.pub' + else: + print("ERROR: Key type error") + exit() + + with open(str(key_path), 'wb') as f: + f.write(key_pem) + + +def generate_keys(): + private_key = generate_private_key() + public_key = generate_public_key(private_key) + return (private_key,public_key) + + +def check_for_existing_keys(): + keys_dir_path = Path.home() / '.auth_server_test' + private_key_path = keys_dir_path / 'id_rsa' + public_key_path = keys_dir_path / 'id_rsa.pub' + + # ========================================================= + # Private key file exists ? Load it + # --- Public key file exists ? Load it + # --- No Public key file ? Generate it from the Private + # No Private key file ? Generate both keys (save as well) + # ========================================================= + + if(private_key_path.exists()): + print('Find private key from file [ OK ]') + # Load private key from file + print('Load private key from file [ ... ]') + with open(str(private_key_path), "rb") as key_file: + private_key = serialization.load_pem_private_key( + key_file.read(), + password=None, + backend=default_backend() + ) + print('Load private key from file [ OK ]') + if(public_key_path.exists()): + print('Find public key from file [ OK ]') + # Load public key from file + print('Load public key from file [ ... ]') + with open(str(public_key_path), "rb") as key_file: + public_key = serialization.load_pem_public_key( + key_file.read(), + backend=default_backend() + ) + print('Load public key from file [ OK ]') + # Return keys + return (private_key,public_key) + else: + print('Find public key from file [ FAIL ]') + print('Generating public key from private key [ ... ]') + public_key = generate_public_key(private_key) + print('Generating public key from private key [ OK ]') + return (private_key,public_key) + else: + print('Find private key from file [ FAIL ]') + print('New keys will be generated') + return generate_keys() + + +#check_for_existing_keys() diff --git a/utils/rsa_tenamortech_utils.py b/utils/rsa_tenamortech_utils.py new file mode 100644 index 0000000..964780f --- /dev/null +++ b/utils/rsa_tenamortech_utils.py @@ -0,0 +1,107 @@ +#=========================================================================================== +# _____ _____ _ _ _ __ __ ___ ____ _____ _____ ____ _ _ +# |_ _| ____| \ | | / \ | \/ |/ _ \| _ \_ _| ____/ ___| | | | +# | | | _| | \| | / _ \ | |\/| | | | | |_) || | | _|| | | |_| | +# | | | |___| |\ |/ ___ \| | | | |_| | _ < | | | |__| |___| _ | +# |_| |_____|_| \_/_/ \_\_| |_|\___/|_| \_\|_| |_____\____|_| |_| +# +# RSA Utils V1 (Python 3.6) +# +# Sources: +# https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/ +# https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python +# https://stackoverflow.com/questions/273192/how-can-i-safely-create-a-nested-directory +# +#=========================================================================================== + +# Basic cryptography tools +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa + +# To format created key obj into text to be used/exported +from cryptography.hazmat.primitives import serialization + +# To get user home directory +from pathlib import Path + +# Encryption +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding + +def generate_private_key(host): + # Generate Private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + backend=default_backend() + ) + save_key(private_key, 0, host) + return private_key + + +def generate_public_key(host, private_key): + # Get Public key from Private + public_key = private_key.public_key() + save_key(public_key, 1, host) + return public_key + + +def private_key_serializer(private_key): + # Key serialization + private_key_pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + return private_key_pem + + +def public_key_serializer(public_key): + # Key serialization + public_key_pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + #print(public_key_pem) + return public_key_pem + + +def save_key(key, key_type, host): + root_file_path = '.auth_server_test/' + if host == 0: + path = root_file_path + 'server' + elif host == 1: + path = root_file_path + 'client' + keys_dir_path = Path.home() / path + # Path exists ? If not we will create it + keys_dir_path.mkdir(exist_ok=True) + if(key_type == 0): + key_pem = private_key_serializer(key) + key_path = keys_dir_path / 'id_rsa' + elif(key_type == 1): + key_pem = public_key_serializer(key) + key_path = keys_dir_path / 'id_rsa.pub' + else: + print("ERROR: Key type error") + exit() + + with open(str(key_path), 'wb') as f: + f.write(key_pem) + + +def generate_keys(host): + private_key = generate_private_key(host) + public_key = generate_public_key(host,private_key) + return (private_key,public_key) + +def encrypt_msg(msg,public_key): + enc_msg = public_key.encrypt( + msg, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), + label=None + ) + ) + return enc_msg + diff --git a/utils/send_receive.py b/utils/send_receive.py new file mode 100644 index 0000000..6ea5ad7 --- /dev/null +++ b/utils/send_receive.py @@ -0,0 +1,35 @@ +#=============================================================== +# --- (Un)Pack msg length and msg itself --- +#=============================================================== +from struct import * +import asyncio, socket + +def send_msg(sock, msg): + # Prefix each message with a 4-byte length (network byte order) + msg = struct.pack('>I', len(msg)) + msg + sock.sendall(msg) + +def send_msg_async(writer, msg): + # Prefix each message with a 4-byte length (network byte order) + msg = struct.pack('>I', len(msg)) + msg + writer.write(msg) + #sock.sendall(msg) + +def recv_msg(reader): + # Read message length and unpack it into an integer + raw_msglen = reader.read(255) + if not raw_msglen: + return None + msglen = unpack('>I', raw_msglen)[0] + # Read the message data + return recvall(reader) + +def recvall(reader, n): + # Helper function to recv n bytes or return None if EOF is hit + data = bytearray() + while len(data) < n: + packet = reader.read(n - len(data)) + if not packet: + return None + data.extend(packet) + return data diff --git a/utils/server_keys_manager.py b/utils/server_keys_manager.py new file mode 100644 index 0000000..938584c --- /dev/null +++ b/utils/server_keys_manager.py @@ -0,0 +1,75 @@ +#=========================================================================================== +# _____ _____ _ _ _ __ __ ___ ____ _____ _____ ____ _ _ +# |_ _| ____| \ | | / \ | \/ |/ _ \| _ \_ _| ____/ ___| | | | +# | | | _| | \| | / _ \ | |\/| | | | | |_) || | | _|| | | |_| | +# | | | |___| |\ |/ ___ \| | | | |_| | _ < | | | |__| |___| _ | +# |_| |_____|_| \_/_/ \_\_| |_|\___/|_| \_\|_| |_____\____|_| |_| +# +# RSA Server Keys Manager V1 (Python 3.6) +# +# Sources: +# https://nitratine.net/blog/post/asymmetric-encryption-and-decryption-in-python/ +# https://stackoverflow.com/questions/8933237/how-to-find-if-directory-exists-in-python +# https://stackoverflow.com/questions/273192/how-can-i-safely-create-a-nested-directory +# +#=========================================================================================== + +# Basic cryptography tools +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import rsa + +# To format created key obj into text to be used/exported +from cryptography.hazmat.primitives import serialization + +# To get user home directory +from pathlib import Path + +# Home made RSA Keys lib +from rsa_tenamortech_utils import * + +def check_for_existing_keys(): + keys_dir_path = Path.home() / '.auth_server_test' / 'server' + private_key_path = keys_dir_path / 'id_rsa' + public_key_path = keys_dir_path / 'id_rsa.pub' + + # ========================================================= + # Private key file exists ? Load it + # --- Public key file exists ? Load it + # --- No Public key file ? Generate it from the Private + # No Private key file ? Generate both keys (save as well) + # ========================================================= + + if(private_key_path.exists()): + print('Find private key from file [ OK ]') + # Load private key from file + print('Load private key from file [ ... ]') + with open(str(private_key_path), "rb") as key_file: + private_key = serialization.load_pem_private_key( + key_file.read(), + password=None, + backend=default_backend() + ) + print('Load private key from file [ OK ]') + if(public_key_path.exists()): + print('Find public key from file [ OK ]') + # Load public key from file + print('Load public key from file [ ... ]') + with open(str(public_key_path), "rb") as key_file: + public_key = serialization.load_pem_public_key( + key_file.read(), + backend=default_backend() + ) + print('Load public key from file [ OK ]') + # Return keys + return (private_key,public_key) + else: + print('Find public key from file [ FAIL ]') + print('Generating public key from private key [ ... ]') + public_key = generate_public_key(0,private_key) + print('Generating public key from private key [ OK ]') + return (private_key,public_key) + else: + print('Find private key from file [ FAIL ]') + print('New keys will be generated') + return generate_keys(0) +check_for_existing_keys()