def pre_key_generation(self): if self.pre_dh_state == 0: sys.stdout.write("Pre Key Generation Started. Please Wait...\n") self.dh = DH() self.pre_dh_state = 1 sys.stdout.write("Pre Key Generation Completed.\n") self.display()
def handshake(self, p, q): #generating DH self.demoDH = DH() self.setDH(p, q) #not necessary to do this as line 88 self.demoDH.setSytemPrameters(self.p, self.q) self.private_DH = self.demoDH.setPrivate( ) #DH: selecting private key first then public key self.public_DH = self.demoDH.setPublic( ) #generate public key, this goes to the server
def handshake(self, p, q): # generate DH self.demoDH = DH() self.setDH(p, q) #not necessary to do this self.demoDH.setSytemPrameters(self.p, self.q) self.private_DH = self.demoDH.setPrivate( ) #private first and public after private is random select self.public_DH = self.demoDH.setPublic( ) # for create session key and this goes to the user
def addConnection(self, connectionPort, receivedKey=None): if receivedKey: self.connections[connectionPort] = {"name":None, "dh": DH(self.mySecretKey)} self.connections[connectionPort]["dh"].computeSharedKey(receivedKey) self.sendKeyToConnection(connectionPort, False) else: self.connections[connectionPort] = {"name":None, "dh": DH(self.mySecretKey)} self.sendKeyToConnection(connectionPort, True) print("Added connection",connectionPort)
def __init__(self, myPort, mySecretKey, myName, addressOfPublicServer=10009): self.myName = myName self.myPort = myPort self.mySecretKey = mySecretKey self.myDH = DH(self.mySecretKey) self.addressOfPublicServer = addressOfPublicServer self.signaturePublicKey, self.signaturePrivateKey = getKeys() ## as strings self.connections = {} self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('localhost',self.myPort)) self.registerToNetwork() self.receiveThread = threading.Thread(target=self.receiveThreadFunction, name=self.myName) self.receiveThread.start() self.currentNewConnectionPublicKey = None self.networkActivityLoggerPort = 10010
def keyReceived(self, connectionPort, dataDict): digitalSignature = dataDict["digitalSignature"] self.getPublicKeyForNewConnection(connectionPort) publicKey = dataDict["publicKey"] #print("Key received from -", connectionPort, ", digitalSignature -",digitalSignature, ", public key -", publicKey,", signaturePublicKey -", self.currentNewConnectionPublicKey) # print("for debug " ,decryptor(digitalSignature, self.currentNewConnectionPublicKey),connectionPort) if decryptor(digitalSignature, self.currentNewConnectionPublicKey) != publicKey: print("Error - unexpected behaviour") return if connectionPort in self.connections: # connection port in dictionary self.connections[connectionPort]["dh"].computeSharedKey(dataDict["publicKey"]) self.connections[connectionPort]["name"] = dataDict["name"] if dataDict["requestKey"]: # other needs key self.sendKeyToConnection(connectionPort) else: # connection port not in dictionary # receive new connection self.connections[connectionPort] = {"name":dataDict["name"], "dh": DH(self.mySecretKey, dataDict["publicKey"])} if dataDict["requestKey"]: self.sendKeyToConnection(connectionPort) print("Log - new connection",dataDict["name"],"added")
class TestDH(unittest.TestCase): # create a DH object and # set a fixed prvsecret instead of a random number def setUp(self): self.alice = DH(321, 2203) self.alice.prvsecret = 12 self.bob = DH(321, 2203) self.bob.prvsecret = 19 def test_gen_pubkey(self): self.assertEqual(self.alice.gen_pubkey(), 486) self.assertEqual(self.bob.gen_pubkey(), 1876) def test_gen_shared_secret(self): self.assertEqual(self.alice.gen_shared_secret(1876), 956) self.assertEqual(self.bob.gen_shared_secret(486), 956) def test_set_shared_secret(self): self.alice.set_shared_secret(1876) self.bob.set_shared_secret(486) self.assertEqual(self.alice.sharedsecret, self.bob.sharedsecret) def test_DH_init(self): self.assertRaises(ValueError, DH, 2, 2)
class Client: def __init__(self, myPort, mySecretKey, myName, addressOfPublicServer=10009): self.myName = myName self.myPort = myPort self.mySecretKey = mySecretKey self.myDH = DH(self.mySecretKey) self.addressOfPublicServer = addressOfPublicServer self.signaturePublicKey, self.signaturePrivateKey = getKeys() ## as strings self.connections = {} self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind(('localhost',self.myPort)) self.registerToNetwork() self.receiveThread = threading.Thread(target=self.receiveThreadFunction, name=self.myName) self.receiveThread.start() self.currentNewConnectionPublicKey = None self.networkActivityLoggerPort = 10010 # registers to network // sends public key to public def registerToNetwork(self): print("Registering to network") messageDict = {"type": "register", "signaturePublicKey":self.signaturePublicKey, "name": self.myName} self.logNetworkActivity(messageDict) self.sock.sendto(self.dictToBinary(messageDict), ("localhost",self.addressOfPublicServer)) print("Done") # get signaturePublicKey def getPublicKeyForNewConnection(self, connectionPort): receiverThread = threading.Thread(target=self.receiveFromPublicThreadFunction, name="signature receiver thread") receiverThread.start() messageDict = {"type": "verify", "entityAddress": connectionPort} self.logNetworkActivity(messageDict) self.sock.sendto(self.dictToBinary(messageDict), ('localhost',self.addressOfPublicServer)) receiverThread.join() def receiveFromPublicThreadFunction(self): while True: data, recvAddress = self.sock.recvfrom(4096) dataDict = self.binaryToDict(data) if dataDict["type"]=="receiveSignaturePublicKey": self.currentNewConnectionPublicKey = dataDict["signaturePublicKey"] break # receive encrypted message def messageReceived(self, connectionPort, dataDict): if self.connections[connectionPort]["dh"].getSharedKey(): print("Message from",self.connections[connectionPort]["name"],"-",decrypt(dataDict["message"],self.connections[connectionPort]["dh"].getSharedKey())) else: print("Error - Key not available to decrypt") # receive key def keyReceived(self, connectionPort, dataDict): digitalSignature = dataDict["digitalSignature"] self.getPublicKeyForNewConnection(connectionPort) publicKey = dataDict["publicKey"] #print("Key received from -", connectionPort, ", digitalSignature -",digitalSignature, ", public key -", publicKey,", signaturePublicKey -", self.currentNewConnectionPublicKey) # print("for debug " ,decryptor(digitalSignature, self.currentNewConnectionPublicKey),connectionPort) if decryptor(digitalSignature, self.currentNewConnectionPublicKey) != publicKey: print("Error - unexpected behaviour") return if connectionPort in self.connections: # connection port in dictionary self.connections[connectionPort]["dh"].computeSharedKey(dataDict["publicKey"]) self.connections[connectionPort]["name"] = dataDict["name"] if dataDict["requestKey"]: # other needs key self.sendKeyToConnection(connectionPort) else: # connection port not in dictionary # receive new connection self.connections[connectionPort] = {"name":dataDict["name"], "dh": DH(self.mySecretKey, dataDict["publicKey"])} if dataDict["requestKey"]: self.sendKeyToConnection(connectionPort) print("Log - new connection",dataDict["name"],"added") # thread that receives messages by listening to connection def receiveThreadFunction(self): while True: data, recvAddress = self.sock.recvfrom(4096) dataDict = self.binaryToDict(data) recvPort = recvAddress[1] # routing request appropriatly if dataDict["type"]=="message": self.messageReceived(recvPort, dataDict) if dataDict["type"]=="key": self.keyReceived(recvPort, dataDict) # make new conn def addConnection(self, connectionPort, receivedKey=None): if receivedKey: self.connections[connectionPort] = {"name":None, "dh": DH(self.mySecretKey)} self.connections[connectionPort]["dh"].computeSharedKey(receivedKey) self.sendKeyToConnection(connectionPort, False) else: self.connections[connectionPort] = {"name":None, "dh": DH(self.mySecretKey)} self.sendKeyToConnection(connectionPort, True) print("Added connection",connectionPort) # send shared key to all def sendKeyToConnection(self, connectionPort, requestKey=False): digitalSignature = self.generateDigitalSignature(self.myDH.getPublicKey()) messageDict = {"type": "key", "name": self.myName, "publicKey": self.connections[connectionPort]["dh"].getPublicKey(), "requestKey": requestKey, "digitalSignature":digitalSignature} # for _ in messageDict.keys(): # print(type(messageDict[_])) self.logNetworkActivity(messageDict) self.sock.sendto(self.dictToBinary(messageDict),('localhost',connectionPort)) # send encrypted message def sendMessage(self, connectionPort, message): if type(connectionPort) is str: for conn in self.connections: if self.connections[conn]==connectionPort: connectionPort = conn break if self.connections[connectionPort]["dh"].getSharedKey() is None: # shared key not available print("Error - channel not protected") else: # shared key available encryptedMessage = encrypt(message, self.connections[connectionPort]["dh"].getSharedKey()) messageDict = {"type": "message","name": self.myName, "message": encryptedMessage} self.logNetworkActivity(messageDict) self.sock.sendto(self.dictToBinary(messageDict),('localhost',connectionPort)) # region utility functions def logNetworkActivity(self, message): if type(message) is type({1:1}): self.sock.sendto(self.dictToBinary(message), ("localhost", 10010)) else: self.sock.sendto(message, ("localhost", 10010)) def generateDigitalSignature(self, connectionPort): return encryptor(connectionPort, self.signaturePrivateKey) def connectionsStatus(self): print("No. of connections -", len(self.connections)) for conn in self.connections: print(" Connection name -",self.connections[conn]["name"], end=", ") self.connections[conn]["dh"].toString() def dictToBinary(self, inputDict): tempJSON = pickle.dumps(inputDict) return tempJSON def binaryToDict(self, inputBinary): # tempJSON = inputBinary.decode() return pickle.loads(inputBinary) # endregion
def create_public_keys(self): self.log(f'Creating public keys...') key_1 = sympy.randprime(2**17, 2**18) key_2 = DH.primRoots(key_1)[0] self.log(f'Public Keys created {key_1} - {key_2}') return (key_1, key_2)
#!/usr/bin/env python """ example diffie-hellman keyexchange for more information about DH see: http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange """ from DH import DH PRIMITIVE_ROOT = 42 PRIME = 44318 ALICE = DH(PRIMITIVE_ROOT, PRIME) print "ALICE: g=%i, p=%i" % (ALICE.in_g, ALICE.in_p) print "ALICE: secret: %i" % ALICE.prvsecret print "ALICE: pubkey: %s\n" % ALICE.gen_pubkey() BOB = DH(PRIMITIVE_ROOT, PRIME) print "BOB: g=%i, p=%i" % (BOB.in_g, BOB.in_p) print "BOB: secret: %i" % BOB.prvsecret print "BOB: pubkey: %s\n" % BOB.gen_pubkey() print "keyexchange..." ALICE.set_shared_secret(BOB.gen_pubkey()) BOB.set_shared_secret(ALICE.gen_pubkey()) print "ALICE shared: %s" % ALICE.sharedsecret print "BOB shared: %s" % BOB.sharedsecret
def setUp(self): self.alice = DH(321, 2203) self.alice.prvsecret = 12 self.bob = DH(321, 2203) self.bob.prvsecret = 19
class User: def __int__( self ): #construct the components NOT give values as Python returns no attributes...don't know why self.userID = None self.message = None """ public key components of the server """ self.n_RSA = 0 # n = p*q self.e_RSA = 0 self.sigG_RSA = 0 """ public key components of the user DH """ self.p_DH = 0 self.q_DH = 0 self.public_DH = 0 """ private key components of the user DH """ self.private_DH = 0 self.sessionKey = 0 """ HMAC """ self.demoHMAC = None self.messageHMAC = None self.taylorArray = [] #setup phase def setUser(self, new_ID, new_message): #update user here because of no attributes error self.userID = new_ID self.message = new_message def setRSA(self, new_e, new_N, new_sigG): #update RSA self.e_RSA = new_e self.n_RSA = new_N self.sigG_RSA = new_sigG def sigVerfication(self): #verify by the user hash = SHA256.new(data=self.message.encode('utf-8')) hash = hash.digest() hash = int.from_bytes(hash, byteorder='big') if hash == FME(self.sigG_RSA, self.e_RSA, self.n_RSA): #if hashed "hello" is sigG return True def getMessage(self): #for printing out "Hello" can replace return self.message def getUserID(self): #for sending USerID, that's all return self.userID #handshake phase def setDH(self, new_p, new_q): #p and q are given self.p = new_p self.q = new_q def handshake(self, p, q): #generating DH self.demoDH = DH() self.setDH(p, q) #not necessary to do this as line 88 self.demoDH.setSytemPrameters(self.p, self.q) self.private_DH = self.demoDH.setPrivate( ) #DH: selecting private key first then public key self.public_DH = self.demoDH.setPublic( ) #generate public key, this goes to the server def session(self, public_key_S): self.sessionKey = self.demoDH.setSession( public_key_S) #by Server Public key def getPublic_DH(self): return self.public_DH def getSession_DH(self): return self.sessionKey #data exchange phase def dataExchange(self): #generate data exchange components here self.demoHMAC = HMAC() self.demoCBC = CBC() self.demoCBC.createKey( self.sessionKey ) #user generate CBC keys: neither Server or User is okay, but only one of them def getKey(self): return self.demoCBC.getKey( ) #16 bytes Assume the connection is secured and this must be top-secret def getIV(self): return self.demoCBC.getIV( ) #16 bytes Assume the connection is secured and this must be top-secret def HMAC1( self ): #Before exchange the message original one goes to the server for authorization taylor = "I was seven, and you were nine I looked at you like the stars th" m = self.demoHMAC.HMAC(self.sessionKey, taylor) # assume this is tag return m # string type def dataExchange2(self): #encrypting the message return as array taylor = "I was seven, and you were nine I looked at you like the stars th" self.taylorArray = self.demoCBC.encrypt( taylor) #already session and IV are created in line 106 return self.taylorArray def setHMAC(self, m): #set the server HMAC value for decrypted message self.messageHMAC = m def dataExchange3(self, swift): #decrypt partial messages and return as string msg = self.demoCBC.decrypt(swift) if self.messageHMAC == self.demoHMAC.HMAC(self.sessionKey, msg): # verification check print("Authorized Server") else: print("Who are you?")
class Transport: def __init__(self): self.uri = None self.socket = None self.shared_secret = None self.pre_dh_state = 0 self.dh = None self.secret_chat = 0 self.o = None self.org = None def connect(self, ip, port): self.uri = (ip, port) csocket = socket(AF_INET, SOCK_STREAM) try: csocket.connect(self.uri) self.socket = csocket return True except: return False def isseen(self): state = self.socket.recv(4).decode() if state == "SEEN": return True def start_secret_chat(self): self.socket.send(b"STARTSECCHAT") data = self.socket.recv(15).decode() if data == "STARTSECCHATACK": return True exit("Peer refused chat or timeout reached!") def send(self, message): self.socket.send(message) if self.isseen(): return True return True def pre_key_generation(self): if self.pre_dh_state == 0: sys.stdout.write("Pre Key Generation Started. Please Wait...\n") self.dh = DH() self.pre_dh_state = 1 sys.stdout.write("Pre Key Generation Completed.\n") self.display() def communicate(self): self.pre_key_generation() while True: rList, wList, error_sockets = select.select([self.socket, sys.stdin], [], []) for sock in rList: if sock == self.socket: data = sock.recv(1024) if self.secret_chat == 1 and data[:4] != b"SEEN" and data[:15] != b"STARTSECCHATREQ": msg_key = data[:16] d_msg = self.o.decrypt(data, msg_key, self.org) sock.send(b"SEEN") return d_msg if data[:15] == b"STARTSECCHATREQ" and self.secret_chat == 0: answer = input("New secret chat request. Do you want to accept? (Y/n): ") if answer.lower() == "y" or answer.lower() == '': self.org = "op" self.socket.send(b"STARTSECCHATACK") else: self.socket.send(b"STARTSECCHATNACK") sys.stdout.write("Peer refused secret chat connection!\n") self.display() elif data[:16] == b"STARTSECCHATNACK": sys.stdout.write("Peer refused secret chat connection!\n") self.display() elif data[:15] == b"STARTSECCHATACK": self.org = "org" self.dh.gen_private() self.socket.send(b"DHPARAMS" + self.dh.dh_parameters) elif data[:8] == b"DHPARAMS": self.dh.dh_parameters = data[8:] self.dh.gen_private() self.dh.gen_public() self.socket.send(b"PPUBLICKEY" + self.dh.public_key) elif data[:10] == b"PPUBLICKEY": peer_pub_key = data[10:] self.shared_secret = self.dh.gen_shared_key(peer_pub_key) self.o = Oracle(self.shared_secret) self.secret_chat = 1 sys.stdout.write("Secret shared key generated\n") self.display() sys.stdout.write("~~~ [+] Secret chat started [+] ~~~\n") self.display() if self.dh.public_key is None: self.dh.gen_public() self.socket.send(b"PPUBLICKEY" + self.dh.public_key) elif data[:4] == b"SEEN": sys.stdout.write("[*] Seen\n") self.display() else: sock.send(b"SEEN") return data else: msg = sys.stdin.readline() if msg.strip() == "/help": sys.stdout.write("/help : Help /secret : Starting secret chat\n") self.display() elif msg.strip() == "/secret": if self.secret_chat == 0: self.socket.send(b"STARTSECCHATREQ") return "SENT" else: return b"Secret chat already established." elif self.secret_chat == 1 and self.shared_secret is not None: e_msg = self.o.encrypt(msg.encode(), self.org) if self.socket.send(e_msg): return "SENT" elif self.socket.send(msg.encode()) and msg != '': return "SENT" def display(self): you = "\33[33m\33[1m> \33[0m" sys.stdout.write(you) sys.stdout.flush()
import sys from DH import DH from random import randint a = DH(sys.maxsize - 1, 5).setPrivateKey(randint(0, 99999)) b = DH(sys.maxsize - 1, 5).setPrivateKey(randint(0, 88888)) a.setForeignKey(b.sharedKey) b.setForeignKey(a.sharedKey) print(a.sessionKey) print(b.sessionKey)
class Server: def __int__(self): self.bits = 0 self.IDs = 0 self.serverID = None self.message = None self.demoRSA = None """ pirvate key components must be hidden """ self.p_RSA = 0 self.q_RSA = 0 self.d_RSA = 0 """ public key components """ self.n_RSA = 0 # n = p*q self.e_RSA = 0 # this value is given self.sigG_RSA = 0 #sigG = hash(message)^d mod n, I use SHA 256 for the hash self.hashedMessage_RSA = 0 #for verification phase self.sigV_RSA = None #sigV = 1 is if hash(message) = sigG^e mod n self.demoDH = None """ DH components """ self.p_DH = 0 self.q_DH = 0 self.public_DH = 0 """ private key components of the user DH """ self.private_DH = 0 self.sessionKey = 0 """ HMAC """ self.demoHMAC = None self.messageHMAC = None self.swiftArray = [] # set up phase def updateRSAKeys(self): """ pirvate key components must be hidden """ self.p_RSA = self.demoRSA.getP() self.q_RSA = self.demoRSA.getQ() self.d_RSA = self.demoRSA.getD() """ public key components """ self.n_RSA = self.demoRSA.getN() self.sigG_RSA = self.demoRSA.getSigG( ) #sigG = hash(message)^d mod n, I use SHA 256 for the hash self.hashedMessage_RSA = self.demoRSA.getHashedM( ) #for verification phase self.sigV_RSA = None #sigV = 1 is if hash(message) = sigG^e mod n def setKey(self, message, new_bits): #generate the RSA ans IDs self.message = message self.bits = new_bits self.e_RSA = 65537 # this value is given self.demoRSA = RSA() self.demoRSA.RSA(self.bits, self.e_RSA) self.demoRSA.sigGeneration(self.message) self.updateRSAKeys() self.IDs = int(1780119054 * random.random()) #not necessary to generate self.serverID = 1780119054 #just give -> can change any numbers """ public key components """ def getN(self): return self.n_RSA def getE(self): return self.e_RSA def getSigG(self): return self.sigG_RSA def getIDs(self): return self.IDs def getServerID(self): return self.serverID #handshake phase def setDH(self, new_p, new_q): #p and q are given self.p = new_p self.q = new_q def handshake(self, p, q): # generate DH self.demoDH = DH() self.setDH(p, q) #not necessary to do this self.demoDH.setSytemPrameters(self.p, self.q) self.private_DH = self.demoDH.setPrivate( ) #private first and public after private is random select self.public_DH = self.demoDH.setPublic( ) # for create session key and this goes to the user def session(self, public_key_U): self.sessionKey = self.demoDH.setSession( public_key_U) #generate by User public key def getPublic_DH(self): return self.public_DH def getSession_HD(self): return self.sessionKey #data exchange phase def dataExchange( self ): #generate components no need to create session and IV as the user does self.demoHMAC = HMAC() self.demoCBC = CBC() def setData(self, sessionkey, IVA): #this must be top-secret self.demoCBC.setkey(sessionkey, IVA) def setHMAC(self, m): #for the user verfication message self.messageHMAC = m def dataExchange2(self, taylor): #decrypt the partial messages, para is arrray msg = self.demoCBC.decrypt(taylor) # return as string if self.messageHMAC == self.demoHMAC.HMAC(self.sessionKey, msg): #check verification print("Authorized User") else: print("Who are you?") def HMAC1(self): #for the server verfication message swift = "at shined In the sky, the pretty lights. And our daddies used to" m = self.demoHMAC.HMAC(self.sessionKey, swift) return m # string type def dataExchange3(self): #encrypt the message swift = "at shined In the sky, the pretty lights. And our daddies used to" self.swiftArray = self.demoCBC.encrypt(swift) return self.swiftArray
def create_shared_key(self, key_1, key_2): self.log('Creating Shared Key...') self.dh = DH(key_2, key_1) self.dh.create_shared_key() self.log('Shared Key Created!') return self.dh.shared_key
class Messenger(wx.Frame): def __init__(self): super().__init__(parent=None, title='CryptoChat Application') self.InitUI() self.Centre() self.makeMenuBar() self.CreateStatusBar() self.log( "Write your usser name and Server Address, then Click to connect..." ) self.Show() self.connected = False self.sessionOpen = False self.dh = None self.users = {} def InitUI(self): panel = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) hbUser = wx.BoxSizer(wx.HORIZONTAL) self.lblUser = wx.StaticText(panel, label='User Name') self.txtUser = wx.TextCtrl(panel) hbUser.Add(self.lblUser, flag=wx.RIGHT, border=8) hbUser.Add(self.txtUser, proportion=1) vbox.Add(hbUser, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=10) vbox.Add((-1, 5)) hbServer = wx.BoxSizer(wx.HORIZONTAL) self.lblSever = wx.StaticText(panel, label='Server Address') self.txtServer = wx.TextCtrl(panel, value='http://localhost:5000') self.btnConnect = wx.Button(panel, label='Connect') hbServer.Add(self.lblSever, flag=wx.RIGHT, border=8) hbServer.Add(self.txtServer, proportion=1) hbServer.Add(self.btnConnect, proportion=0.5) vbox.Add(hbServer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=10) vbox.Add((-1, 10)) hbUsers = wx.BoxSizer(wx.HORIZONTAL) self.lblUsers = wx.StaticText(panel, label='Connected users') self.cmbUsers = wx.ComboBox(panel) self.btnChatWith = wx.Button(panel, label='Chat...') hbUsers.Add(self.lblUsers, flag=wx.RIGHT, border=8) hbUsers.Add(self.cmbUsers, proportion=1) hbUsers.Add(self.btnChatWith, proportion=0.5) vbox.Add(hbUsers, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=10) vbox.Add((-1, 10)) hbChat = wx.BoxSizer(wx.HORIZONTAL) lblChat = wx.StaticText(panel, label='Chat Box') hbChat.Add(lblChat) vbox.Add(hbChat, flag=wx.LEFT | wx.TOP, border=10) vbox.Add((-1, 10)) hbChatBx = wx.BoxSizer(wx.HORIZONTAL) self.txtChat = rt.RichTextCtrl(panel, style=wx.VSCROLL | wx.HSCROLL | wx.TE_READONLY) hbChatBx.Add(self.txtChat, proportion=1, flag=wx.EXPAND) vbox.Add(hbChatBx, proportion=1, flag=wx.EXPAND | wx.RIGHT | wx.EXPAND, border=10) hbMsg = wx.BoxSizer(wx.HORIZONTAL) self.txtMsg = wx.TextCtrl(panel) self.btnSendMsg = wx.Button(panel, label='Send') hbMsg.Add(self.txtMsg, proportion=1) hbMsg.Add(self.btnSendMsg, proportion=0.3) vbox.Add(hbMsg, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=10) vbox.Add((-1, 10)) panel.SetSizer(vbox) self.cmbUsers.Enabled = False self.btnChatWith.Enabled = False self.btnConnect.Bind(wx.EVT_BUTTON, self.OnConnect) self.btnChatWith.Bind(wx.EVT_BUTTON, self.OnChatWith) self.btnSendMsg.Bind(wx.EVT_BUTTON, self.OnSendMsg) self.initControls() def log(self, msg): self.SetStatusText(msg) logger.info(msg) def initControls(self): self.cmbUsers.Enabled = False self.btnChatWith.Enabled = False self.txtChat.Enabled = False self.txtMsg.Enabled = False self.btnSendMsg.Enabled = False def makeMenuBar(self): fileMenu = wx.Menu() exitItem = fileMenu.Append(wx.ID_EXIT) helpMenu = wx.Menu() aboutItem = helpMenu.Append(wx.ID_ABOUT) menuBar = wx.MenuBar() menuBar.Append(fileMenu, "&File") menuBar.Append(helpMenu, "&Help") self.SetMenuBar(menuBar) self.Bind(wx.EVT_MENU, self.OnExit, exitItem) self.Bind(wx.EVT_MENU, self.OnAbout, aboutItem) def create_public_keys(self): self.log(f'Creating public keys...') key_1 = sympy.randprime(2**17, 2**18) key_2 = DH.primRoots(key_1)[0] self.log(f'Public Keys created {key_1} - {key_2}') return (key_1, key_2) def create_shared_key(self, key_1, key_2): self.log('Creating Shared Key...') self.dh = DH(key_2, key_1) self.dh.create_shared_key() self.log('Shared Key Created!') return self.dh.shared_key def create_full_key(self, shared_key): self.log(f'Creating Full key with shared key {shared_key}...') self.dh.create_full_key(shared_key) def next_key(self): self.log("Generating new private key...") self.dh.next_key() self.log('Creating Shared Key...') self.log( f'Shared Key Created! {self.dh.private_key} - {self.dh.shared_key}' ) return self.dh.shared_key def OnConnect(self, event): if not self.connected: #Connect to web server self.log("Connecting to server...") #try: self.btnConnect.LabelText = 'Disconnect' user = self.txtUser.Value server = self.txtServer.Value sio.connect(server) self.log( f'Connected to server {server} with user {user} session id:{sio.sid}' ) sio.emit('login', {'session': sio.sid, 'user': user}) self.cmbUsers.Clear() self.connected = True # except: # err = sys.exc_info()[0] # log(f"System error! {err}") else: #Disconnect self.log("Disconecting from server...") self.btnConnect.LabelText = 'Connect' sio.emit('logout', { 'session': sio.sid, 'user': self.txtUser.Value }) self.connected = False self.log("Disconnected") sio.disconnect() self.txtUser.Enabled = not self.connected self.txtServer.Enabled = not self.connected self.initControls() def OnChatWith(self, event): user = self.cmbUsers.GetStringSelection() key_1, key_2 = self.create_public_keys() requester_shared_key = self.create_shared_key(key_1, key_2) data = { 'requester': self.txtUser.Value, 'requester_sid': sio.sid, 'requester_shared_key': requester_shared_key, 'user': user, 'user_sid': self.users[user], 'user_shared_key': None, 'key_1': key_1, 'key_2': key_2 } self.log(f'Sending chat request to user {user}...') sio.emit('chatwith', data) def OnSendMsg(self, event): msg = self.txtMsg.Value now = datetime.datetime.now() nowStr = now.strftime("%Y-%m-%d %H:%M:%S") if len(msg): msg = f'{nowStr} \t {self.txtUser.Value}: {self.txtMsg.Value}' self.txtChat.BeginTextColour((255, 0, 0)) self.txtChat.WriteText(msg) self.txtChat.EndTextColour() self.txtChat.Newline() self.log('Encrypting message...') enc = self.dh.encrypt(msg) user = self.cmbUsers.GetStringSelection() s_id = self.users[user] data = { 'requester': self.txtUser.Value, 'requester_sid': sio.sid, 'requester_shared_key': self.dh.shared_key, 'user': user, 'user_sid': s_id, 'user_shared_key': None, 'enc': enc } self.log(f'Sending Encrypted message...{enc}') sio.emit('sendmessage', data) self.txtMsg.Clear() def decryptMessage(self, enc): msg = self.dh.decrypt(enc) self.log('Decrypting message...') self.txtChat.BeginTextColour((0, 150, 100)) self.txtChat.WriteText(msg) self.txtChat.EndTextColour() self.txtChat.Newline() self.log('Message decrypted!') def OnExit(self, event): """Close the frame, terminating the application.""" self.Close(True) def OnAbout(self, event): """Display an About Dialog""" message = ''' Author: Asahi Cantu Moreno Application Description: This project emulates the diffe-hallman encryption mechanism to securely send messages from the web from one user to another. Created for the assignment of Network Security and Cryptography for the University of Stavanger ''' wx.MessageBox(message, "About Client Application", wx.OK | wx.ICON_INFORMATION)