diff --git a/client.py b/client.py index 952c331..b652c7e 100644 --- a/client.py +++ b/client.py @@ -1,11 +1,24 @@ +from cryptography.fernet import Fernet import threading import requests import time import rsa import os + class Client: + def _key_gen(self) -> None: + + (pubkey, privkey) = rsa.newkeys(512) + + with open("private.pem", "wb") as f: + f.write(privkey.save_pkcs1()) + + with open("public.pem", "wb") as f: + f.write(pubkey.save_pkcs1()) + + def __init__(self, username: str): self.server = "95.165.158.131" self.port = 80 @@ -18,6 +31,9 @@ class Client: self.key_url = f"{self.base_url}/get_key" self.pubkey = None + self.privkey = None + self.symetric_key = None + self.fernet = None def send_info(self): @@ -26,7 +42,8 @@ class Client: user_input = input("You're message: ") message = f'{self.username}: {user_input}' requests.post(self.talk_url, data={ - "text": rsa.encrypt(message.encode('utf8'), self.pubkey) + "text": self.fernet.encrypt(message.encode()), + "username": self.username }) @@ -39,27 +56,42 @@ class Client: continue last_try = r.json() os.system("cls") - for msg in last_try["status"]: - print(f"{rsa.decrypt(msg.encode(), self.seckey)}\n") + if len(last_try['status']) > 0: + i = 0 + for msg in last_try["status"]: + actual_message = self.fernet.decrypt(msg.encode()).decode("utf-8") + if i == 0: + users = last_try["users_in_chat"] + print(f"Users in chat: {users}\n\n") + print(f"{actual_message}\n") + else: + print(f"{actual_message}\n") + i += 1 def _key_request(self) -> None: + with open('private.pem', 'rb') as f: + self.privkey = rsa.PrivateKey.load_pkcs1(f.read()) - with requests.get(self.key_url) as r: - with open("public_rec.pem", 'wb') as f: - f.write(r.text.encode()) + with open("public.pem", 'rb') as f: + with requests.get(self.key_url, data={"pubkey": f.read(), "username": self.username}, stream=True) as r: + message = r.raw.read(999) + self.symetric_key = rsa.decrypt(message, self.privkey) + self.fernet = Fernet(self.symetric_key) + def _remove_keys(self) -> None: - with open('public_rec.pem', 'wb') as f: - pass + os.remove("private.pem") + os.remove("public.pem") def _validate_keys(self) -> None: + self._key_gen() self._key_request() - with open('public_rec.pem', "rb") as f: + with open('public.pem', "rb") as f: first_key = f.read() self.pubkey = rsa.PublicKey.load_pkcs1(first_key) @@ -80,5 +112,5 @@ class Client: if __name__ == '__main__': - c = Client("sneaky") # input("Who are you? \t") + c = Client(input("Who are you? \t")) c() \ No newline at end of file diff --git a/preview.png b/preview.png index b7d72ee..bafeb52 100644 Binary files a/preview.png and b/preview.png differ diff --git a/readme.MD b/readme.MD index 7fe08e5..c34d034 100644 --- a/readme.MD +++ b/readme.MD @@ -1,4 +1,4 @@ -here is simple online chat what can be runned in cmd +here is secured online chat what can be runned in cmd ![preview](preview.png) @@ -16,11 +16,8 @@ how to run clear client * pip install -r reqs.txt * python client.py -to do -* rsa - -potential crypting pipeline +crypting pipeline * Client making priv key * Server making symmetric key @@ -28,4 +25,8 @@ potential crypting pipeline * Server crypting symmetric key and sending to client * Client encrypting private key * And than communicate with server via -* symmetric key \ No newline at end of file +* symmetric key + +to do + +* interface for choosing server in client \ No newline at end of file diff --git a/reqs.txt b/reqs.txt index b70bae6..c4277cf 100644 --- a/reqs.txt +++ b/reqs.txt @@ -1,3 +1,4 @@ sanic requests -rsa \ No newline at end of file +rsa +cryptography \ No newline at end of file diff --git a/server.py b/server.py index d5f59c6..8d77610 100644 --- a/server.py +++ b/server.py @@ -2,21 +2,17 @@ from email.policy import HTTP from typing import Any, Coroutine from sanic import Sanic, Request, response from sanic.response import HTTPResponse +from cryptography.fernet import Fernet from sanic.server.websockets.impl import WebsocketImplProtocol + import rsa app = Sanic("app") app.config.OAS = False actual_messages = [] - -(pubkey, privkey) = rsa.newkeys(512) - -with open("private.pem", "wb") as f: - f.write(privkey.save_pkcs1()) - -with open("public.pem", "wb") as f: - f.write(pubkey.save_pkcs1()) +users = {} +key = Fernet.generate_key() @app.route('/talk', methods=["GET", "POST"]) @@ -27,9 +23,16 @@ async def talking(request: Request) -> HTTPResponse: @app.route('/update', methods=["GET", "POST"]) async def talking(request: Request) -> HTTPResponse: - return response.json({"status": [rsa.encrypt(k.encode('utf8'), pubkey) for k in actual_messages]}) + return response.json({"status": actual_messages, "users_in_chat": list(users.keys())}) @app.route('/get_key', methods=['GET', 'POST']) async def get_key(request: Request) -> HTTPResponse: - return await response.file("public.pem", status=200) \ No newline at end of file + + pubkey = rsa.PublicKey.load_pkcs1(request.form['pubkey'][0]) + data = rsa.encrypt(key, pubkey) + + if request.ip not in users: + users[request.form['username'][0]] = key + + return response.raw(data) \ No newline at end of file