server.py
from socket import *
from threading import *
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
length = 4096
key = RSA.generate(2048)
public_key = key.publickey()
host = '127.0.0.1'
port = int(input("Enter a port: "))
server = socket(AF_INET, SOCK_STREAM)
server.bind((host,port))
server.listen()
print(f"Server running on {host}:{port}")
clients = []
usernames = []
usrs_keys = {}
def broadcast(msg, _client,username):
for client in clients:
if client != _client:
public_client_key = usrs_keys[username]
encryptor = PKCS1_OAEP.new(public_client_key)
encrypt_msg = encryptor.encrypt(msg)
client.send(encrypt_msg)
def handle_messages(client,address):
while True:
index = clients.index(client)
username = usernames[index]
try:
msg = client.recv(length)
encryptor = PKCS1_OAEP.new(key)
decrypt_msg = encryptor.decrypt(msg)
broadcast(decrypt_msg, client,username)
except:
broadcast(f"ChatBot: {username} disconnected".encode('utf-8'),client,username)
clients.remove(client)
usernames.remove(username)
client.close()
print(f"{username} disconnected from {str(address)}")
break
def recive_conn():
while True:
global usrs_keys
client, address = server.accept()
client.send("@username!".encode('utf-8'))
username = client.recv(length).decode('utf-8')
client.send("key!".encode('utf-8'))
usr_public_key = RSA.importKey(client.recv(length), passphrase=None)
usrs_keys[username] = usr_public_key
client.send(key.publickey().exportKey(format='PEM', passphrase=None, pkcs=1))
clients.append(client)
usernames.append(username)
print(f"{username} connected from {str(address)}")
msg = f'ChatBot: {username} joined the chat.'.encode('utf-8')
broadcast(msg, client,username)
client.send("Successful connection".encode('utf-8'))
thread = Thread(target=handle_messages, args=(client,address))
thread.start()
recive_conn()
client.py
from socket import *
from threading import *
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
ACCEPTED_CHARS = ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','_','.')
ctl = 0
length = 4096
while True:
user = input("Enter your username: ")
for i in user:
if i not in ACCEPTED_CHARS:
ctl += 1
if ctl != 0:
print('Error: invalid character(s)')
else:
break
host = input("Enter an ip: ")
while True:
try:
port = int(input("Enter a port: "))
break
except:
print("Error: Invalid port")
key = RSA.generate(2048)
server_key = None
client = socket(AF_INET, SOCK_STREAM)
client.connect((host,port))
def handle_keys():
try:
if client.recv(length).decode('utf-8') == "@username!":
client.send(user.encode('utf-8'))
elif client.recv(length).decode('utf-8') == 'key!':
global server_key
client.send(key.publickey().exportKey(format='PEM', passphrase=None, pkcs=1))
server_key = RSA.importKey(client.recv(length), passphrase=None)
except:
print("An unexpected error has occurred!")
ssl_client.close()
def recive_msg():
while True:
try:
msg = client.recv(length)
encryptor = PKCS1_OAEP.new(key)
decrypt_msg = encryptor.decrypt(msg)
print('@'+decrypt_msg.decode('utf-8'))
except:
print("An unexpected error has occurred!")
client.close()
break
def write_msg():
while True:
entry = input('$')
msg = f'{user}: {entry}'
encryptor = PKCS1_OAEP.new(server_key)
encrypt_msg = encryptor.encrypt(msg.encode('utf-8'))
client.send(encrypt_msg.encode('utf-8'))
recv_thread = Thread(target=recive_msg)
recv_thread.start()
write_thread = Thread(target=write_msg)
write_thread.start()
Everything works fine but when the client connects to the server the server gives an error but I don't understand what is wrong this is the error it gives me
Traceback (most recent call last):
File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 77, in <module>
recive_conn()
File "C:\Users\delaf\OneDrive\Escritorio\armadillo\server.py", line 61, in recive_conn
usr_public_key = RSA.importKey(ssl_client.recv(length), passphrase=None)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
I removed some comments so the lines that the error says may not match but there is all the code
I don't know if the "length" variable is too small or if it can't be any value, I also don't know if it affects the port I use for the tests, which is 42069 (it's obvious why) or if I have to configure the firewall to open that port (although I don't think so because I'm working locally). sorry if my english is not very good or there are translation errors but i speak spanish