def authenticate_me(self, pwdHash): #print "authenticate with chat server and set up session key" ret = False if self.serverPublicKey is not None: # step 1: send authentication message msg = "AUTH:" if not self.send_message(msg, self.serverAddr, self.port): return ret # step 2: receive challenge and starting number serverResponse = self.receive_response() if(serverResponse is None): return ret challengeAndStartingNum = serverResponse.split(":") challenge = int(challengeAndStartingNum[0],16) startingNum = int(challengeAndStartingNum[1]) #************************************************** # Start authentication procedure (Augmented PDM) #************************************************** # step 3: solve challenge and send APDM contribution challenge_response = self.solve_challenge(challenge, startingNum) a = CryptoLib.generateRandomKey(16) # retrieve the safe prime for the user p = genPrime.genp(self.username, self.password) # step 4: generate client contribution (2^a mod p) and send challenge response, # client user name and contribution to server Note: no need to encrypt because eavesdropper # cannot compute 2^W mod p client_contribution = pow(ChatClient.generator, int(a.encode('hex'), 16), p) msg = "CONTRIBUTION:" + str(challenge_response) + ":" + self.username + ":" + str(client_contribution) #msg = CryptoLib.encryptUsingPublicKey(self.serverPublicKey, msg) if not self.send_message(msg, self.serverAddr, self.port): return ret # step 5: receive server contribution and shared key hash serverResponse = self.receive_response() if(serverResponse is None): print "failed to receive response from server" return ret serverContributionAndHash = serverResponse.split(":") serverContribution = serverContributionAndHash[0] serverSessionKeyHash = serverContributionAndHash[1] # step 6: calculate session key and hash W = pwdHash # 2^ab mod p sharedKey1 = CryptoLib.generateSecretKey(int(serverContribution), int(a.encode('hex'), 16), p) # 2^bW mod p sharedKey2 = CryptoLib.generateSecretKey(int(serverContribution), int(W, 16), p) #print "===== W: ", W sessionKey = (str(sharedKey1) + str(sharedKey2))[0:16] if self.DBG: print "sharedKey1: %s, sharedKey2: %s, sessionKey: %s, len: %d" % \ (sharedKey1, sharedKey2, sessionKey, len(sessionKey)) # HASH(2^ab mod p, 2^bW modp) sessionKeyHash = CryptoLib.generateKeyHash(sessionKey) if(serverSessionKeyHash == sessionKeyHash): self.sessionKey = sessionKey self.sessionID = serverContributionAndHash[2] if self.DBG: print"====== session keys match!! sessionID %s, len: %d " % \ (self.sessionID, len(self.sessionID)) # step 7: send hash of encrypted session key and public key to server self.clientPrivateKey, self.clientPublicKey = CryptoLib.generatePublicPrivateKeys() validateServer = int(CryptoLib.generateRandomKey(16).encode("hex"), 16) #msg = "VALIDATE:" + sessionKeyHash + ":" + self.clientPublicKey + ":" + validateServer msg = "VALIDATE:" + sessionKeyHash + ":" + str(validateServer) + ":" + self.clientPublicKey msg = CryptoLib.encyptUsingSymmetricKey(self.sessionKey, self.sessionID, msg) if not self.send_message(msg, self.serverAddr, self.port): return ret # server signals that client has been fully authenticated response = self.receive_response() if response is None: print "Error!!! didn't receive response from server" return ret response = CryptoLib.decryptUsingSymetricKey(self.sessionKey, self.sessionID, response) response = response.split(":") if self.DBG is True: print "validateServer: %s, serverResponse: %s" % (str(validateServer), response[1]) if response[0] == "ACKNOWLEDGE" and \ int(validateServer + 1 == int(response[1])): ret = True # End of authentication with server. return ret
def authenticateMe(self, pwdHash): print "authenticate with chat server and set up session key" ret = False if self.serverPublicKey is not None: # step 1: send authentication message msg = "authenticate me" if self.sendMessage(msg, self.serverAddr, self.port) is False: return ret # step 2: receive challenge and starting number servermsg = self.receiveMessage() challenge_starting = servermsg.split(":") challenge = challenge_starting[0] starting_num = challenge_starting[1] # step 3: handle challenge and generate response as well as response = self.solvechallenge(challenge, starting_num) msg = response if self.sendMessage(msg, self.serverAddr, self.port) is False: return ret # Start authentication procedure (Augmented PDM) a = random.randrange(1, 100) # retrieve the safe prime for the user p = genPrime.genp(self.username, self.password) # send 2^a modp to server msg = pow(2, a) % p if self.sendMessage(msg, self.serverAddr, self.port) is False: return ret b = self.receiveMessage() # TODO: get W for client W = pwdHash # HASH(2^ab modp, 2^bW modp) hash_msg_client = hash(str((pow(2, (a*b)) % p)) + ":" + str((pow(2, (b*W)) % p))) msg = "send hash" if self.sendMessage(msg, self.serverAddr, self.port) is False: return ret hash_msg_server = self.receiveMessage() if hash_msg_client == hash_msg_server: ret = True # End of authentication with server. # Diffie Hellman contribution # TODO: handle challenge received and generate response clientContribution = CryptoLib.generateDHContribution(ChatClient.generator, ChatClient.prime) # step 4: encrypt client contribution and send response clientCipher = CryptoLib.encryptUsingPublicKey(self.serverPublicKey, clientContribution) msg = "Response:todo:%s:%s" % (self.username, clientCipher) if self.sendMessage(msg, self.serverAddr, self.port) is False: return ret # step 5: receive server contribution and hash serverContribution = self.receiveMessage() # step 6: TODO: calculate session key and hash # step 7: send server client's public key ret = True return ret