def auth_proof(self, client_proof, nonce): """Returns Server signature given Client proof and combined nonce""" try: client_nonce, server_nonce, session = self._get_session(nonce) except ServerNonceException: raise ServerNonceException record = self.__record.read(session['username']) auth_message = Scram.auth_message_generation(session['username'], client_nonce, session['salt'], self.IC, server_nonce) client_signature = Scram.signature_generation(record['stored_key'], auth_message) server_signature = Scram.signature_generation(record['server_key'], auth_message) if Scram.stored_key_generation( Utils.bitwise_xor(client_proof, client_signature)) != record['stored_key']: raise Exception("Verification failed") return {"server_signature": server_signature}
def generate_user(self, username): """Returns Client username, Client password, random salt, ic, Client key and Server Key, given Client username""" password = Utils.generate_password() salt = Utils.nonce(self.SALT_SIZE) salted_password = Scram.salted_password(password, salt, self.IC) client_key = Utils.key_generation(self.KEY_SIZE) server_key = Utils.key_generation(self.KEY_SIZE) server_client_key = Utils.hmac_generation(salted_password, client_key) server_server_key = Utils.hmac_generation(salted_password, server_key) stored_key = Scram.stored_key_generation(server_client_key) record = { "stored_key": stored_key, "server_key": server_server_key, "salt": salt, "ic": self.IC } self._save_record(username, record) return { "username": username, "password": password, "salt": salt, "ic": self.IC, "client_key": client_key, "server_key": server_key }
def registration_keys_generation(self, secret_server_key, secret_client_key, nonce): """Returns Client key, server key and stored key, given encrypted "Server key" and encrypted "Slient key" and combined nonce""" if self.__data['nonce'] != nonce: raise ClientNonceException client_key = Utils.bitwise_xor(secret_client_key, self.__data['shared_key']) server_key = Utils.bitwise_xor(secret_server_key, self.__data['shared_key']) client_client_key = Utils.hmac_generation( self.__data['salted_password'], client_key) client_server_key = Utils.hmac_generation( self.__data['salted_password'], server_key) client_stored_key = Scram.stored_key_generation(client_client_key) return_value = { "server_key": client_server_key, "client_key": client_client_key, "stored_key": client_stored_key } self.__data = {} self.__data = { "server_key": client_server_key, "client_key": client_client_key, "stored_key": client_stored_key } return return_value
def server_auth(self, server_signature): """Verifies the correctness of the given Server signature""" client_server_signature = Scram.signature_generation( self.__data['server_key'], self.__data['auth_message']) if client_server_signature != server_signature: raise Exception("Verification failed")
def auth_client_proof_generation(self, nonce, salt, ic): """Returns combined nonce and Client proof, given combined nonce, salt and ic by the Server""" try: client_nonce, server_nonce = self._check_nonce(nonce) except ClientNonceException: raise ClientNonceException if client_nonce != self.__data['nonce']: raise ClientNonceException self.__data['auth_message'] = Scram.auth_message_generation( self.__data['username'], client_nonce, salt, ic, server_nonce) client_signature = Scram.signature_generation( self.__data['stored_key'], self.__data['auth_message']) self.__data['client_proof'] = Scram.client_proof_generation( self.__data['client_key'], client_signature) return {"nonce": nonce, "client_proof": self.__data['client_proof']}
def server_auth(self, server_signature): """Verifies the correctness of the given Server signature""" client_server_signature = Scram.signature_generation( self.__data['server_key'], self.__data['auth_message']) #https://docs.python.org/2/library/hmac.html #if client_server_signature != server_signature: if not hmac.compare_digest(client_server_signature, server_signature): raise Exception("Verification failed")
def auth_pairing(self, username, client_key, server_key): """Returns username and a random Client nonce, given Client key and Server key""" self.__data['nonce'] = Utils.nonce(self.NONCE_SIZE) self.__data['username'] = username self.__data['client_key'] = client_key self.__data['server_key'] = server_key self.__data['stored_key'] = Scram.stored_key_generation( self.__data['client_key']) return {"username": username, "client_nonce": self.__data['nonce']}
def registration_keys_generation(self, nonce, secret_key): """Returns encrypted "Client key", encrypted "Server key" and combined nonce and delete the session""" try: client_nonce, server_nonce, session = self._get_session(nonce) except ServerNonceException: raise ServerNonceException salted_password = Utils.bitwise_xor(secret_key, session['shared_key']) client_key = Utils.key_generation(self.KEY_SIZE) server_key = Utils.key_generation(self.KEY_SIZE) server_client_key = Utils.hmac_generation(salted_password, client_key) server_server_key = Utils.hmac_generation(salted_password, server_key) stored_key = Scram.stored_key_generation(server_client_key) # creare db username self.__record.write( session['username'], { "stored_key": stored_key, "server_key": server_server_key, "salt": session['salt'], "ic": self.IC }) return_value = { "secret_server_key": Utils.bitwise_xor(server_key, session['shared_key']), "secret_client_key": Utils.bitwise_xor(client_key, session['shared_key']), "nonce": nonce } self.__sessions.delete_session(client_nonce) return return_value
def registration_send_password(self, salt, ic, public_key, nonce): """Returns encrypted salted password and combined nonce, given salt, ic, Server public key and Server nonce by the Server""" try: self.__data['shared_key'] = self.__dh.shared_secret(public_key) client_nonce, server_nonce = self._check_nonce(nonce) except DHBadKeyException: raise DHBadKeyException except ClientNonceException: raise ClientNonceException if client_nonce != self.__data['nonce']: raise ClientNonceException self.__data['nonce'] = client_nonce + "-" + server_nonce self.__data['salted_password'] = Scram.salted_password( self.__data['password'], salt, ic) secret_salted_password = Utils.bitwise_xor( self.__data['salted_password'], self.__data['shared_key']) return { "secret_key": secret_salted_password, "nonce": self.__data['nonce'], }