def peer_response(self, key, ticket, peer_username): # Step 1: Decrypt and split the ticket to get the information of the client ret = False ticket = CryptoLib.decryptUsingSymetricKey(key, self.sessionID, ticket) ticket = ticket.split(":") peer_address = ticket[0] peer_public_key = ticket[1] peer = Peer.Peer(peer_username, peer_address, peer_public_key) # Step 2: Generate and send contribution b = CryptoLib.generatePublicPrivateKeys(32) msg = pow(2, b, self.peerPrime) msg = CryptoLib.encryptUsingPublicKey(peer_public_key, msg) if not self.send_message(msg, peer_address[0], peer_address[1]): return ret # Step 3: Recieve peer contribution and iv and unpack it peer_contribution = self.receive_response() peer_contribution = CryptoLib.decryptUsingPrivateKey(self.clientPrivateKey, peer_contribution) peer_contribution = peer_contribution.split(":") peer_session_id = peer_contribution[1] peer_contribution = peer_contribution[0] # Construct shared key shared_key = pow(peer_contribution, b, self.peerPrime) # Step 4: Challenge Response (Two way authentication) - user sends challenge, client increments and sends # back response which is again incremented and sent back to user. All of this is done using the symmetric # key encryption with the shared key. challenge = random.randrange(1, 100000) challenge = CryptoLib.encyptUsingSymmetricKey(shared_key, peer_session_id, challenge) if not self.send_message(challenge, peer_address[0], peer_address[1]): return ret response = self.receive_response() response = CryptoLib.decryptUsingSymetricKey(shared_key, peer_session_id, response) # If authentication is successful, add the peer to list of connected peers and send back response if response == challenge + 1: response += 1 response = CryptoLib.encyptUsingSymmetricKey(shared_key, peer_session_id, response) if not self.send_message(response, peer_address[0], peer_address[1]): return ret peer.set_initialization_vector(peer_session_id) peer.set_shared_key(shared_key) self.peers[peer_address] = peer return True return False
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