def exchangeDHCli(socket, sharedPassphrase=PASSPHRASE): if VERBOSE_MODE: globalTimeStart = time.clock() print("\n \n Starting DH key derivation algorithm...") print("------------------------------------------") print('\nGenerating public keys... ') print("-> Generator: ", GENERATOR) print("-> Group (p): ", GROUP) else: print("Starting DH key derivation algorithm...\nPlease wait...") if MEASURE_TIME: start = time.clock() dhObjClient = DiffieHellman(GENERATOR, GROUP, KEY_LENGTH) A = dhObjClient.genPublicKey() if MEASURE_TIME: end = time.clock() if VERBOSE_MODE: print("-> A: ", A) if MEASURE_TIME: print("{0:.5f} sec".format(end - start)) print('\n') print('Encrypting A with the passphrase... ') if MEASURE_TIME: start = time.clock() EncrObj = Encryption(sharedPassphrase) encryptedA = EncrObj.encrypt(jsonpickle.encode(A)) if MEASURE_TIME: end = time.clock() message = {'Identity': 'ClientA', 'EncData': encryptedA.decode('utf-8'), 'Generator': GENERATOR, 'Group': GROUP} serialisedParameters = jsonpickle.encode(message) if VERBOSE_MODE: if MEASURE_TIME: print("{0:.5f} sec".format(end - start)) print("\nSend packet to Server: ", serialisedParameters) print('\n') MessageUtils.send_one_message(socket, serialisedParameters) # We just sent: # message => {Identity, EncryptedData, Generator, Group(where the prime is found)} # receive Servers message! serversPubParams = MessageUtils.recv_one_message(socket) if VERBOSE_MODE: print("Packet received: ") if (not serversPubParams): if VERBOSE_MODE: print("-> Server responded with empty! ") return else: # we should have received Server's identity and the encrypted Tb + a random number serversIdentity = serversPubParams['Identity'] serversEnc = serversPubParams['EncData'] if VERBOSE_MODE: print("-> Identity: ", serversIdentity) print("-> EncData: ", serversEnc) print('\n') if MEASURE_TIME: start = time.clock() serversPar = EncrObj.decrypt(serversEnc) serversDecodedPar = jsonpickle.decode(serversPar.decode('utf-8')) if MEASURE_TIME: end = time.clock() Tb = serversDecodedPar['Tb'] serverRandom = serversDecodedPar['ServerRandom'] if VERBOSE_MODE: print("Decrypted EncData: ") print("-> Tb: ", Tb) print("-> ServerRandom: ", serverRandom) print("{0:.5f} sec".format(end - start)) # generate the shared key if VERBOSE_MODE: print('\n') print("Deriving session key...") if MEASURE_TIME: start = time.clock() dhObjClient.genKey(Tb) derived_secret = str(dhObjClient.getKey()) if MEASURE_TIME: end = time.clock() if VERBOSE_MODE: print("-> Derived Key: ", derived_secret) if MEASURE_TIME: print("{0:.5f} sec".format(end - start)) print("\n\n *** Sending test data *** \n\n ") # This is the Test Phase! clientRandomNumber = str(dhObjClient.genRandom(KEY_LENGTH)) if VERBOSE_MODE: print("Choosing random number...") testMessage = {"ServerRandom": serverRandom, "ClientRandom": clientRandomNumber} serializeTestMessage = jsonpickle.encode(testMessage) if VERBOSE_MODE: print("Create packet: ", testMessage) if MEASURE_TIME: start = time.clock() newEncryption = Encryption(derived_secret) encryptedMessage = newEncryption.encrypt(serializeTestMessage) if MEASURE_TIME: end = time.clock() if VERBOSE_MODE: print("Encry. packet: ", encryptedMessage) if MEASURE_TIME: print("{0:.5f} sec\n".format(end - start)) print("Send packet...\n") MessageUtils.send_one_message(socket, encryptedMessage) # receive the last response ! serversMessage = MessageUtils.recv_one_message(socket) if VERBOSE_MODE: print("Encrypted Packet received: ", serversMessage) if MEASURE_TIME: start = time.clock() decryptServersMessage = newEncryption.decrypt(serversMessage) receivedRandom = decryptServersMessage.decode('utf-8') if MEASURE_TIME: end = time.clock() if VERBOSE_MODE: print("Decrypting Packet... ") if MEASURE_TIME: print("{0:.5f} sec \n".format(end - start)) if (receivedRandom == clientRandomNumber): if VERBOSE_MODE: print("-> Sent random was: ", clientRandomNumber) print("-> Rec. random is : ", receivedRandom) print("\nThe randoms correspond!") globalTimeStop = time.clock() print( "\n\n***** KEY DERIVATION COMPLETED in {0:.5f} sec *****".format(globalTimeStop - globalTimeStart)) print("The session key is: ", hexlify(dhObjClient.getKey())) print("----------------------------------------------------------------------------------------\n\n") else: print("***** Key derivation completed *****") return dhObjClient.getKey() else: if VERBOSE_MODE: print("\nThe received random doesn't correspond to the one that was sent!") print("-> Sent random: ", clientRandomNumber) print("-> Rec. random: ", receivedRandom) print("\n\n***** KEY DERIVATION FAILED *****\n\n") else: print("***** KEY DERIVATION FAILED *****") return None
def exchangeDHServ(socket, sharedPassphrase=PASSPHRASE): if VERBOSE_MODE: globalTimeStart = time.clock() print("\n \n Starting DH key derivation algorithm...") print("------------------------------------------") else: print("Starting DH key derivation algorithm...\nPlease wait...") clientPubParams = MessageUtils.recv_one_message(socket) if VERBOSE_MODE: print("\nPacket received: ") if not clientPubParams: if VERBOSE_MODE: print("-> Client responded with empty! ") return else: if VERBOSE_MODE: print("-> Packet: ", clientPubParams) decodedClientMessage = jsonpickle.decode(clientPubParams) # we got some data: clientsIdentity = decodedClientMessage['Identity'] encryptedData = decodedClientMessage['EncData'] clientGenerator = decodedClientMessage['Generator'] clientGroup = decodedClientMessage['Group'] if VERBOSE_MODE: print('\n') print("Compacting Received Data: ") print("-> Identity: ", clientsIdentity) print("-> EncData: ", encryptedData) print("-> Generator: ", clientGenerator) print("-> Group: ", clientGroup) # we should decrypt the encrypted value if VERBOSE_MODE: print('\n') print("Decrypting EncData (extracting Ta) ...") if MEASURE_TIME: start = time.clock() EncrObj = Encryption(sharedPassphrase) decryptedData = EncrObj.decrypt(encryptedData) if MEASURE_TIME: end = time.clock() Ta = jsonpickle.decode(decryptedData.decode('utf-8')) if VERBOSE_MODE: print("-> Ta: ", Ta) print("{0:.5f} sec".format(end - start)) # now we got all the data so we can derive the key if MEASURE_TIME: start = time.clock() dhObjServer = DiffieHellman(clientGenerator, clientGroup, KEY_LENGTH) dhObjServer.genKey(Ta) derived_secret = str(dhObjServer.getKey()) if MEASURE_TIME: end = time.clock() if VERBOSE_MODE: print('\n') print("Derived key: ", derived_secret) print("{0:.5f} sec".format(end - start)) if MEASURE_TIME: start = time.clock() Tb = dhObjServer.genPublicKey() if VERBOSE_MODE: print("Calculated Tb: ", Tb) if MEASURE_TIME: end = time.clock() print("{0:.5f} sec\n".format(end - start)) # now let's notify the client we got the request! serverRandomNumber = str(dhObjServer.genRandom(KEY_LENGTH)) if VERBOSE_MODE: print("Extracting ServerRandom: ", serverRandomNumber) messageEnc = {'Tb': Tb, 'ServerRandom': serverRandomNumber} serialiseMess = jsonpickle.encode(messageEnc) if VERBOSE_MODE: print('\n') print("Encrypting EncData={Tb,ServerRandom}") if MEASURE_TIME: start = time.clock() encryptedMess = EncrObj.encrypt(serialiseMess) if MEASURE_TIME: end = time.clock() sendMessage = {'Identity': 'Server', 'EncData': encryptedMess} if VERBOSE_MODE: print("-> EncData: ", encryptedMess) if MEASURE_TIME: print("{0:.5f} sec\n".format(end - start)) serialiseSendMessage = sendMessage if VERBOSE_MODE: print('\n') print("Send packet to the client: ", serialiseSendMessage) MessageUtils.send_one_message(socket, serialiseSendMessage) if VERBOSE_MODE: print("Packet sent! ") # second phase completed! now we should test the derived key if VERBOSE_MODE: print("\n\n *** Waiting for test data *** \n\n ") clientMessage = MessageUtils.recv_one_message(socket) if VERBOSE_MODE: print("Received an encrypted packet: ", clientMessage) print("Decrypting packet with the derived key...") if MEASURE_TIME: start = time.clock() newEncryption = Encryption(derived_secret) decryptMessage = newEncryption.decrypt(clientMessage) if MEASURE_TIME: end = time.clock() decodeMessage = jsonpickle.decode(decryptMessage.decode('utf-8')) receivedRandom = decodeMessage['ServerRandom'] getClientRandom = decodeMessage['ClientRandom'] if VERBOSE_MODE: print("\n") print("Decrypted packet: ") print("-> ServerRandom (c1): ", receivedRandom) print("-> ClientRandom (c2): ", getClientRandom) print("{0:.5f} sec\n".format(end - start)) print("\n") if (receivedRandom == serverRandomNumber): if VERBOSE_MODE: print("Sent random: ", serverRandomNumber) print("Rec. random: ", receivedRandom) print("The randoms correspond!") print("Encrypting and sending the client's random Ek(C2)... ") if MEASURE_TIME: start = time.clock() encryptClientRandom = newEncryption.encrypt(getClientRandom) MessageUtils.send_one_message(socket, encryptClientRandom) if VERBOSE_MODE: if MEASURE_TIME: end = time.clock() print("{0:.5f} sec\n".format(end - start)) if VERBOSE_MODE: globalTimeStop = time.clock() print( "\n\n***** KEY DERIVATION COMPLETED in {0:.5f} sec *****".format(globalTimeStop - globalTimeStart)) print("The session key is: ", hexlify(dhObjServer.getKey())) print("----------------------------------------------------------------------------------------\n\n") else: print("***** Key derivation completed *****") return dhObjServer.getKey() else: if VERBOSE_MODE: print("The received random doesn't correspond to the one that was sent!") print("Sent random: ", serverRandomNumber) print("Rec. random: ", receivedRandom) print("\n\n***** KEY DERIVATION FAILED *****\n\n") else: print("***** KEY DERIVATION FAILED *****") return None
# now we can use the key as we want! ''' as an example is brought a simple echo program! the server gets the messages from the client, decrypts them and if the message says quit the server responds to the client and then closes the socket the client receives quit and closes his socket. ''' if session_key == None: # if Diffie-Hellman didn't offer a key! print("No key derived! ") connectedClientSocket.close() exit(1) else: print("Now we can send encrypted messages! ") message1 = "Hi. This is the server. You can send me messages securely now and i will eco back! If you want to quit just type \'quit\'" MessageUtils.send_encrypted_message(connectedClientSocket, message1, session_key) while True: receivedMessage = MessageUtils.receive_encrypted_message(connectedClientSocket, session_key) if receivedMessage != 'quit': MessageUtils.send_encrypted_message(connectedClientSocket, receivedMessage, session_key) else: print("\'quit\' detected, closing connection!") MessageUtils.send_encrypted_message(connectedClientSocket, receivedMessage, session_key) connectedClientSocket.close() break break break
session_key = ExchangeDHCli.exchangeDHCli(tcpSocket) # this is all that's needed to derive the key! ''' as an example is brought a simple echo program. The user inputs a message, the client encrypts it with the session key and then sends it to the server. The server decrypts it checks if it equals to 'quit' and if so it closes the connection. If the message is not quit it echoes the message to the client! The client checks if the message says 'quit' and if so it closes the socket. If not it just asks the user to send another message! ''' if session_key is None: print("No key was derived! ") exit(1) else: print("Now we can send encrypted messages\n\n") message = MessageUtils.receive_encrypted_message(tcpSocket, session_key) print("Server: " + message) while True: mess = input("Type a message: ") if mess == 'quit': print("\'quit\' detected, closing connection ... ") MessageUtils.send_encrypted_message(tcpSocket, mess, session_key) tcpSocket.close() break else: MessageUtils.send_encrypted_message(tcpSocket, mess, session_key) response = MessageUtils.receive_encrypted_message(tcpSocket, session_key) print("Server: ", response) break