コード例 #1
0
ファイル: ChatClient.py プロジェクト: onyeka/SimpleChat
    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
コード例 #2
0
ファイル: ChatClient.py プロジェクト: onyeka/SimpleChat
    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