From 3937416f406ee3afc7539ff7940392fcdcdd06a0 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Wed, 6 Nov 2019 17:48:42 +0100 Subject: [PATCH] split home made libs, begin encryption part --- client_test_2.py | 37 +++++ client_test_3.py | 48 ++++++ server_test_2.py | 30 ++++ server_test_3.py | 53 +++++++ utils/__init__.py | 0 utils/__pycache__/__init__.cpython-36.pyc | Bin 0 -> 160 bytes .../client_keys_manager.cpython-36.pyc | Bin 0 -> 1600 bytes .../__pycache__/keys_manager_1.cpython-36.pyc | Bin 0 -> 2938 bytes .../rsa_tenamortech_utils.cpython-36.pyc | Bin 0 -> 2305 bytes utils/client_keys_manager.py | 75 ++++++++++ utils/keys_manager_1.py | 137 ++++++++++++++++++ utils/rsa_tenamortech_utils.py | 107 ++++++++++++++ utils/send_receive.py | 35 +++++ utils/server_keys_manager.py | 75 ++++++++++ 14 files changed, 597 insertions(+) create mode 100644 client_test_2.py create mode 100644 client_test_3.py create mode 100644 server_test_2.py create mode 100644 server_test_3.py create mode 100644 utils/__init__.py create mode 100644 utils/__pycache__/__init__.cpython-36.pyc create mode 100644 utils/__pycache__/client_keys_manager.cpython-36.pyc create mode 100644 utils/__pycache__/keys_manager_1.cpython-36.pyc create mode 100644 utils/__pycache__/rsa_tenamortech_utils.cpython-36.pyc create mode 100644 utils/client_keys_manager.py create mode 100644 utils/keys_manager_1.py create mode 100644 utils/rsa_tenamortech_utils.py create mode 100644 utils/send_receive.py create mode 100644 utils/server_keys_manager.py 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 0000000000000000000000000000000000000000..e6e4fcc3f6a3fd4367c4ff2cfa664bbd9b867459 GIT binary patch literal 160 zcmXr!<>i`FwKtXl2p)q77+?f49Dul(1xTbY1T$zd`mJOr0tq9CU%vVo`MIh3Wr;bd zc_o>7`V|Eg1x5MkMTxn&i6xo&dHMyFB^f{}HLWN$Q@%uFuu%4zqBMX ir&vEeJ~J<~BtBlRpz;=nO>TZlX-=vg$eLmxW&i+SFDmH( literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c58fb0cabfd93ada53e3cfc8fafde8909608f621 GIT binary patch literal 1600 zcma)7&2J+$6u0LqlQh|Ox0OI`wVH)fkai+=ZwMg}(js70K8nODtIBf5PUCdGWIJgy zN>Aas;_u+!;J}^hTsiF(Zk%}b4BMV6vjfLOpfKcR7#cQ**E z;VBw+UjrT*;(C|yDP5$ROlWe!a|R|?DhgttxD+%M71g51!Qg#M^$aBbAThz_3Sc~d z@i`224P6-D?RP6@dmTb#`*d9 z+SS3lvv%hpU?B~(S@_Dm_I`w?@6h+?g^BB$xV2;PeuL*;i?{Oz&uQ@vEncs|vuOQS z&b9v*+Q6cDYk%sT8uWWD+OCy5Y;WytAO_yt-}cPk14yw(aY$Y zucNc-z2^n}Zs+gm-lGuYxs4TZ%d70K-kT9Dg4EP)}G zJJ1tV)TF!Jvsuku*`9s&<#SkZ`~}asgg(sABPh~aytYgAGP22ELnET<@&698Jl?;v z@GX(U6Mkt*qM}QYrqP5)=M6K?h6CwC+S;2H8LtC=C6rdR5A-`%CyI%W#|KDV!DS|Z)-WUz9VNef@Buq$B!g(FR%y@D^riCQ7bgivk|G7G!1fO>kz}ihp$0SvqEZ~%!svG hs=T^aQ0`+m>*M1 zhH#5`4ql^=;aj+=#1nAE_m8uiY_+Vg<$uO=_|N}0^F^!G@c(-A`s*!C`%_zb4D`Rj zS0o@zV|t>cdZ6pnHxeT?15@?Q#7gbJR(&gR(ppeM-)7FQTHvx8bJ5mWoi)%l*a~Z+ zU12S@inhtt*gD!4+hCh$SJ~FS=5N1+M9tUBHOBkVQ6j@`)H~!E!;mS82u-WtB94-H z63IBvFktOQa?qoF^yv6(e2?%I9*ES2I@6gUjhV*G-^?>jnp2HgGeg&=8f4l#v5sxA z=0dU=tc{MkN!$zh=_t>5CIk17kHaFK@Uk{nMvxHS5+<5*`+#R$M3RRi5g${F^@3bj zxc((E6aXkh-I{mvjydFMDvAScc`r=!!6$PYx6rpma^Xeq6W^l@fA%F&9HO>Z^LNlYNki3(?bf9 z{>o1`(V1#PZKj>+QlG+K$~!u|W9+6gE;v>O*5_f?7ix)Ik7s1P}@;#eB1LdDhEWoE?--KNs*? zu#FM&5^^Jql7n2ta*+D9pmpy5?pX3dSP)*ikI#3TyN`beTDw&MpH!Ue-Di*X9|X;v z9Lwe`=Qblr7O@UTJbl;xo6Ga(3Cl$rQVVhw#l^wfGz5z8vKvS>6_s1)yz2%yz*soI z5NlW?)>V zuphNO?Ps*epvKN*qa7W|K?pOBQ9now`4YA2^3%AGVScCzy>wz00(%4%)TB}UwBdxw zjmLX?FZLdK@Si8gBkpk_a#0#5UB4kHn@fudytLCp77G<=<(1M#dStS+AO|!b@vJlp zDN6eU>B@blG*K@V@DSg!h2J6sk8lL63u^eK$W$w6sMP!Kq@XI%@1R5RK8S`)Yw9lE zMnzGAjbttQi~kGZlp&OF+hfyCjOQtfSe+4GF!Elw5K{^?;!TK z&rInIYg2RRBGWWk2dx1=tVJGRpUND{K=6Bm|N5L? zc1^9RO^yP$)|}g_YF8*P&uomZEw9UNVq|^3aznMv88TF5>E=~gDhRPJ<>H+uamKtk z?0E3D*B5!}_2Yzlue=w}yw{Vv&-3WNm$ch$?{#U2u5SeHC@PARTrfdVncTT{qvGvV z;uXeREq%`9>J>`3uUF!{O5D{eD@(4E_T<~A&tYx*`|4cA;owz>wa{zXO|Lv9eDeAK zUawU6_*#F@b-1;|Pe^Lvoy1Avb-8z556o{Vgb-AnrK13+5QO-G4sY=x5jqKi?F3Py zYG1xzl$PKTQ@4y@Yq3DNOx-`|a8>o?JHjJ2>&qvSLXq=}jsg>c6?M^}g!%7t{k`6R z_YOmxwYVPvBjH>UR|F7IJOlyI5Wv*&0b+Si?tEf!&uUY~F(^$sGyl6+oI8C_}aZlaRf{(6WUpcx)UPk{Cq+mE{VxL>9@J4*Oh1Z4#sfla+>((A6cHMfCx({=s@65rX$ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1c998da4558ba0105f6c38b0cf2396c984536650 GIT binary patch literal 2305 zcmah~TW=dh6rP#A+OeIqOnwud^3xc9O=? z`pJE*`ZwTj@H6(6r~U)P6W`1_bs9ymt2yWFnaiH*H=niJ&0qfh^S2jmLjEEb9tQba zjN%yxC!8iEr2(Z{W(iBJz%sIx*r^jZMz#|-^#aex4)lKD8`;JBM$mxlasL?!n!LfA z;A?!1x4>Jx%{$<2zRowmJNz2I4!+KB@J;XyzI8ylH($aM(xufp7o+GnQQ;sO9*K-Y zWyvA}YZpSsQ4*g;D$X+~?7c{h!QF9Gj70&-n?{_++2N4t)9`3V9gO=J#RnjYOem+E zDYhWodT!0BvP#PBk}TkINnwi9k13%fCO!eIGyI1$W-MYiCI|0XQJ|! zHcI`wt}QLFYV%NJLPko2QyHIVj`dO-Qu#%6Vm`a9vd4L$sBO|EOAy{pLvr0T{hP<4c{^J7dDE(l>hg;h5oU7gHr z%#>t86rHe%1!_+mP#0;XI;|#^td9ixA{*wqDk^uBOT@6+ghs~4ePP<;! zKF`KrrbHoi1S)^`e7Ci?`>1N~)k%F&pXBU4ynpaT)#~S1wmh=SjL*UP`DwadrXs!U z|ILf@=d~^5ZTz)pg6QiRINReh^23v2gien7^+(NP|SYFMme0*xvV;?Y+vQu)`jVnYhPh!fv#G**0Q8- z$)T<`{WO-tRNe3R;B;=G-q;b7H%p6Kx5(ViHlVSg`4AdMYjjI5NNK-K=1%EM7Z60O~tm5GM5#5I_Nf~Ml=l|si>Uv zh{w_thzVxppsD~;Hcki4ry{GYLdnW`iYgb~MrENKYYfxpnjQ^0GS5{wiW7hqFtxHZ z4cb^)ggD+P0}r1%*MR{*vyP4~6}9R7U6^OUmQb7ew26Uc2FPe$e>KtGF594H{j18> zg`kHi0A1M%wT%Q(zz)*6U~^UifJPd4Xdk7h;mlyf|AI~X71(H}e#O2TW{gGhQ+&S$ zejXIYiccVD@GA|_0AMTypfMmrmlCeb=a#We+hz5U+r|o2aFwQqBh%HDlSBiNpbNbv z07?CyzUaQ`zZwg!`)A4L)9Gw9Scb0cpQD0HrtCpao(pbeOqS%RwS(*wZ z<6(WWSbf1;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()