Ejemplo n.º 1
0
    def solve_challenge(self, challenge, num):
        """
        Solve challenge set by server
        :param challenge: server challenge
        :param num: starting value
        :return: number
        """
        if self.DBG:
            print " challenge: %s, num: %s" % (challenge, num)

        response = int(CryptoLib.generateKeyHash(str(num)), 16)
        while response != challenge:
            num += 1
            response = int(CryptoLib.generateKeyHash(str(num)), 16)
            #print " challenge: %x, hash: %x" % (challenge, response)

        return num
Ejemplo n.º 2
0
 def challengeResponse(self):
     # generate a sufficiently large random number
     num = random.randrange(100000, 1000000)
     # generate a random number to subtract from it
     firstFew = random.randrange(1000, 10000)
     firstFew = num - firstFew
     # create the challenge hash
     challenge = CryptoLib.generateKeyHash(str(num))
     return num, challenge, firstFew
Ejemplo n.º 3
0
    def handleClientMessages(self, msg, knownClient, addr):
        if self.DBG is True:print " message received: '%s'" % msg
        msgContents = msg.split(":")

        if msgContents[0] == "AUTH":
            if knownClient is not None:
                print "client has already been Authenticated, ignore message..."
            else:
                self.challengeAnswer, challenge, firstFew = self.challengeResponse()
                response = str(challenge) + ":" + str(firstFew)
                self.sendMessage(response, addr)
        elif msgContents[0] == "CONTRIBUTION":
            if int(msgContents[1]) == self.challengeAnswer:
                if self.DBG is True: print "solved challenge!!!"
                for existingClients in self.clients.values():
                    if existingClients.get_name() == msgContents[2]:
                        print "client already exists, removing old client..."
                        msg = "DISCONNECTED:"
                        msg = CryptoLib.encyptUsingSymmetricKey(existingClients.get_session_key(),
                                                                existingClients.get_initialization_vector(),
                                                                msg)
                        self.sendMessage(msg, existingClients.get_address())
                        self.clients.pop(existingClients.get_address())

                # create and add new client to list
                client = Client.User(msgContents[2], addr)
                self.clients[addr] = client
                #**************************************************
                # Start authentication procedure (Augmented PDM)
                #**************************************************
                clientContribution = msgContents[3]
                b = CryptoLib.generateRandomKey(16)
                # retrieve the safe prime for the user
                primeTag = 'P' + (self.clients[addr]).get_name()
                try:
                    p = ChatServer.config.getint('SectionTwo', primeTag)
                except Exception, e:
                    print "couldn't get prime...: ", e
                    self.clients.pop(addr)
                    return
                # generate server contribution (2^b mod p) to send to server
                serverContribution = pow(ChatServer.generator, int(b.encode('hex'), 16), p)

                # retrieve the password hash for the user
                pwdHashTag = 'W' + (self.clients[addr]).get_name()

                # 2^W mod p
                try:
                    pwdHashExp = ChatServer.config.getint('SectionTwo', pwdHashTag)
                except Exception, e:
                    print "couldn't get pwd hash...: ", e
                    self.clients.pop(addr)
                    return

                #print "2^W mod p for client, pwdHashTag:%s ==> pwdHashExp:%s" % (pwdHashTag, pwdHashExp)

                # 2^ab mod p
                sharedKey1 = CryptoLib.generateSecretKey(int(clientContribution),
                                                     int(b.encode('hex'), 16), p)
                # 2^bW mod p
                sharedKey2 = CryptoLib.generateSecretKey(pwdHashExp, int(b.encode('hex'), 16), p)

                sessionKey = (str(sharedKey1) + str(sharedKey2))[0:16]
                #print "Server: sharedKey1: %s, sharedKey2: %s, sessionKey: %s" % (sharedKey1,
                #                                                      sharedKey2, sessionKey)
                # HASH(2^ab mod p, 2^bW modp)
                sessionKeyHash = CryptoLib.generateKeyHash(sessionKey)
                if self.clients.get(addr) is not None:
                    self.clients.get(addr).set_session_key_and_hash(sessionKey, sessionKeyHash)
                    iv = CryptoLib.generateRandomKey(8).encode('hex')
                    self.clients.get(addr).set_initialization_vector(iv)
                    response = str(serverContribution) + ":" + sessionKeyHash + ":" + iv
                    if self.DBG: print "====== sending: ", response
                    self.sendMessage(response, addr)
                    return
Ejemplo n.º 4
0
    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