Что касается моего последнего проекта в школе, я решил создать защищенную банковскую систему, которая включает шифрование RSA - а частью банка является система чата между клиентами и банкирами.
Я работал в течение нескольких дней, чтобы заставить защищенный чат работать, но я просто не в состоянии ... Кажется, что есть связь между клиентами и сервером, но даже когда он командует GUI, он не отвечает
Почему это происходит?
Буду рад вашей помощи!
Я попытался уладить получение / отправку, чтобы они были в порядке - и не сломит
Я не уверен, действительно ли это сработало.
У меня есть целый код шифрования \ дешифрования RSA - который прекрасно работает
Я сохраняю открытые ключи клиентов в диктофоне, и в целом все должно работать нормально.
"""Script for Tkinter GUI chat client."""
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
from random import randrange, getrandbits
def is_prime(n, k=128):
""" Test if a number is prime
Args:
n -- int -- the number to test
k -- int -- the number of tests to do
return True if n is prime
"""
# Test if n is not even.
# But care, 2 is prime !
if n == 2 or n == 3:
return True
if n <= 1 or n % 2 == 0:
return False
# find r and s
s = 0
r = n - 1
while r & 1 == 0:
s += 1
r //= 2
# do k tests
for _ in range(k):
a = randrange(2, n - 1)
x = pow(a, r, n)
if x != 1 and x != n - 1:
j = 1
while j < s and x != n - 1:
x = pow(x, 2, n)
if x == 1:
return False
j += 1
if x != n - 1:
return False
return True
def generate_prime_candidate(length):
""" Generate an odd integer randomly
Args:
length -- int -- the length of the number to generate, in bits
return a integer
"""
# generate random bits
p = getrandbits(length)
# apply a mask to set MSB and LSB to 1
p |= (1 << length - 1) | 1
return p
def generate_prime_number(length=1024):
""" Generate a prime
Args:
length -- int -- length of the prime to generate, in bits
return a prime
"""
p = 4
# keep generating while the primality test fail
while not is_prime(p, 128):
p = generate_prime_candidate(length)
return p
def KeyEncryption():
n1 = generate_prime_number()
n2 = generate_prime_number()
Phi1 = n1 - 1
Phi2 = n2 - 1
mul = n1 * n2
PhiMul = Phi1 * Phi2
e = 17
d = multiplicative_inverse(e, PhiMul)
return e, mul, d
def multiplicative_inverse(a, b):
"""Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
"""
# r = gcd(a,b) i = multiplicitive inverse of a mod b
# or j = multiplicitive inverse of b mod a
# Neg return values for i or j are made positive mod b or a respectively
# Iterateive Version is faster and uses much less stack space
x = 0
y = 1
lx = 1
ly = 0
oa = a # Remember original a/b to remove
ob = b # negative values from return results
while b != 0:
q = a // b
(a, b) = (b, a % b)
(x, lx) = ((lx - (q * x)), x)
(y, ly) = ((ly - (q * y)), y)
if lx < 0:
lx += ob # If neg wrap modulo orignal b
if ly < 0:
ly += oa # If neg wrap modulo orignal a
# return a , lx, ly # Return only positive values
return lx
def Encryption(msg):
ascii_text = []
encrypted_ascii = ""
for c in msg:
ascii_text.append(ord(c))
for c in ascii_text:
encrypted_ascii = encrypted_ascii + str(pow(c, server_e, server_n)) + "|"
encrypted_ascii = encrypted_ascii[:-1]
return encrypted_ascii
def Decryption(encrypted_ascii):
temp_encrypted_ascii = encrypted_ascii.split("|")
decrypted_ascii = []
decrypted_text = []
for c in temp_encrypted_ascii:
decrypted_ascii.append(pow(int(c), int(client_d), int(client_n)))
for c in decrypted_ascii:
decrypted_text.append(chr(c))
text = ''
for c in decrypted_text:
text += c
return text
def receive():
"""Handles receiving of messages."""
enc_text = client_socket.recv(BUFSIZ).decode("utf8")
enc_data = enc_text.split("|")
global server_e
server_e = int(enc_data[0])
global server_n
server_n = int(enc_data[1])
while True:
try:
enc_msg = client_socket.recv(BUFSIZ).decode("utf8")
msg = Decryption(enc_msg)
msg_list.insert(tkinter.END, msg)
except OSError: # Possibly client has left the chat.
break
def send(event=None): # event is passed by binders.
"""Handles sending of messages."""
enc_data = str(client_e) + "|" + str(client_n)
client_socket.send(bytes(enc_data, "utf8"))
while True:
msg = my_msg.get()
encrypted_msg = Encryption(msg)
my_msg.set("") # Clears input field.
client_socket.send(bytes(encrypted_msg, "utf8"))
if msg == "{quit}":
client_socket.close()
top.quit()
def on_closing(event=None):
"""This function is to be called when the window is closed."""
my_msg.set("{quit}")
send()
#main
top = tkinter.Tk()
top.title("Chatter")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar() # For the messages to be sent.
my_msg.set("")
scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages.
# Following will contain the messages.
msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
#----Now comes the sockets part----
HOST = '127.0.0.1'
PORT = 33000
BUFSIZ = 9999
client_e, client_n, client_d = KeyEncryption()
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
tkinter.mainloop() # Starts GUI execution.
receive_thread = Thread(target=send())
receive_thread.start()
#!/usr/bin/env python3
"""Server for multithreaded (asynchronous) chat application."""
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
from random import randrange, getrandbits
import time
def is_prime(n, k=128):
""" Test if a number is prime
Args:
n -- int -- the number to test
k -- int -- the number of tests to do
return True if n is prime
"""
# Test if n is not even.
# But care, 2 is prime !
if n == 2 or n == 3:
return True
if n <= 1 or n % 2 == 0:
return False
# find r and s
s = 0
r = n - 1
while r & 1 == 0:
s += 1
r //= 2
# do k tests
for _ in range(k):
a = randrange(2, n - 1)
x = pow(a, r, n)
if x != 1 and x != n - 1:
j = 1
while j < s and x != n - 1:
x = pow(x, 2, n)
if x == 1:
return False
j += 1
if x != n - 1:
return False
return True
def generate_prime_candidate(length):
""" Generate an odd integer randomly
Args:
length -- int -- the length of the number to generate, in bits
return a integer
"""
# generate random bits
p = getrandbits(length)
# apply a mask to set MSB and LSB to 1
p |= (1 << length - 1) | 1
return p
def generate_prime_number(length=1024):
""" Generate a prime
Args:
length -- int -- length of the prime to generate, in bits
return a prime
"""
p = 4
# keep generating while the primality test fail
while not is_prime(p, 128):
p = generate_prime_candidate(length)
return p
def multiplicative_inverse(a, b):
"""Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
"""
# r = gcd(a,b) i = multiplicitive inverse of a mod b
# or j = multiplicitive inverse of b mod a
# Neg return values for i or j are made positive mod b or a respectively
# Iterateive Version is faster and uses much less stack space
x = 0
y = 1
lx = 1
ly = 0
oa = a # Remember original a/b to remove
ob = b # negative values from return results
while b != 0:
q = a // b
(a, b) = (b, a % b)
(x, lx) = ((lx - (q * x)), x)
(y, ly) = ((ly - (q * y)), y)
if lx < 0:
lx += ob # If neg wrap modulo orignal b
if ly < 0:
ly += oa # If neg wrap modulo orignal a
# return a , lx, ly # Return only positive values
return lx
def Decryption(encrypted_ascii):
temp_encrypted_ascii = encrypted_ascii.split("|")
decrypted_ascii = []
decrypted_text = []
for c in temp_encrypted_ascii:
decrypted_ascii.append(pow(int(c), server_d, server_n))
for c in decrypted_ascii:
decrypted_text.append(chr(c))
text = ''
for c in decrypted_text:
text += c
return text
def accept_incoming_connections():
"""Sets up handling for incoming clients."""
enc_data = str(server_e) + "|" + str(server_n)
while True:
client, client_address = SERVER.accept()
print("%s:%s has connected." % client_address)
client.send(bytes(enc_data, "utf8"))
temp_key = client.recv(BUFSIZ).decode("utf8")
print(temp_key)
addresses[client] = client_address
Thread(target=handle_client, args=(client, temp_key,)).start()
def handle_client(client, temp_key): # Takes client socket as argument.
"""Handles a single client connection."""
welcome = "Enter your name"
key = temp_key.split("|")
enc_welcome = Encryption(welcome, key[0], key[1])
print(enc_welcome)
client.send(bytes(enc_welcome, "utf8"))
enc_name = client.recv(BUFSIZ).decode("utf8")
name = Decryption(enc_name)
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
client.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat!" % name
broadcast(bytes(msg, "utf8"))
clients[client] = name
Encryption_keys[name] = temp_key
while True:
msg_enc = client.recv(BUFSIZ).decode("utf8")
msg = Decryption(msg_enc)
if msg != bytes("{quit}", "utf8"):
broadcast(msg_enc, name + ": ")
else:
client.send(bytes("{quit}", "utf8"))
client.close()
del clients[client]
broadcast(bytes("%s has left the chat." % name, "utf8"))
break
def Encryption(text, e, n):
ascii_text = []
encrypted_ascii = ""
for c in text:
ascii_text.append(ord(c))
for c in ascii_text:
encrypted_ascii = encrypted_ascii + str(pow(c, int(e), int(n))) + "|"
encrypted_ascii = encrypted_ascii[:-1]
return encrypted_ascii
def broadcast(msg, prefix=""): # prefix is for name identification.
"""Broadcasts a message to all the clients."""
count = 0
for sock in clients:
temp_key = Encryption_keys[count]
temp_e = temp_key[0]
temp_n = temp_key[1]
enc_msg = Encryption(temp_e, temp_n)
sock.send(bytes(prefix, "utf8") + bytes(str(enc_msg), "utf8"))
count = count + 1
def KeyEncryption():
n1 = generate_prime_number()
n2 = generate_prime_number()
Phi1 = n1 - 1
Phi2 = n2 - 1
mul = n1 * n2
PhiMul = Phi1 * Phi2
e = 17
d = multiplicative_inverse(e, PhiMul)
return e, mul, d
clients = {}
addresses = {}
Encryption_keys = {}
server_e, server_n, server_d = KeyEncryption()
HOST = ''
PORT = 33000
BUFSIZ = 9999
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)
if __name__ == "__main__":
SERVER.listen(5)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=accept_incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
Я ожидаю, что графический интерфейс будет работать так, как должен, потому что теперь он только входит в разрушение, а не отвечает