def end_authentication(self, n2): iv = base64.b64encode(os.urandom(16)) n3 = fcrypt.generate_nonce(32) response_to_client = pickle.dumps(AuthVerify(n2, n3), pickle.HIGHEST_PROTOCOL) encrypted_response_to_client, tag = fcrypt.symmetric_encryption(self.shared_dh_key, iv, response_to_client) msg = dict() msg['type'] = MessageStatus.END_AUTH msg['data'] = fcrypt.asymmetric_encryption(self.server_pub_key, iv) + LINE_SEPARATOR + \ fcrypt.asymmetric_encryption(self.server_pub_key, tag) + LINE_SEPARATOR + \ encrypted_response_to_client self.client_sock.sendall(json.dumps(msg)) isResultValid, decrypted_nonce_res = self.receive_encrypted_data_from_server(False) if isResultValid and long(decrypted_nonce_res) == long(n3) + 1: return True else: return False
def connect_to_client(self, target_client_info): # start authentication process target_client_info.n3 = fcrypt.generate_nonce() msg = ConnMsg( self.user_name, self.client_ip, self.client_port, fcrypt.serialize_pub_key(self.rsa_pub_key), target_client_info.ticket, target_client_info.iv, target_client_info.tag, target_client_info.ticket_signature, target_client_info.n3, '', '', '', time.time() ) self.send_encrypted_data_to_client(target_client_info, MessageStatus.START_CONN, msg)
def client_handler_for_auth_start(self, client_address, data): response_from_client = pickle.loads( fcrypt.asymmetric_decryption(self.private_key, data)) challenge = response_from_client.solved_challenge # check if the response given to the challenge is correct if challenge != self.users_loggedin[client_address].challenge: return False, ERROR_PROMPT + 'Response to the given challenge is incorrect!' user_name = response_from_client.user_name # the same user cannot login twice user_dict = self.find_user_by_name(user_name) if user_dict is not None and user_dict.state == UserState.AUTHENTICATED: return False, ERROR_PROMPT + 'User is already logged in, please logout and retry!' password = response_from_client.password if not self.check_password(user_name, password): return False, ERROR_PROMPT + 'The user name or password is wrong!' # set user information current_user = self.users_loggedin[client_address] current_user.user_name = response_from_client.user_name current_user.ip = response_from_client.ip current_user.port = int(response_from_client.port) current_user.rsa_pub_key = fcrypt.deserialize_pub_key( response_from_client.rsa_pub_key) current_user.state = UserState.VERIFIED # DH key exchange dh_pri_key, dh_pub_key = fcrypt.generate_dh_key_pair() current_user.dh_pub_key = fcrypt.deserialize_pub_key( response_from_client.dh_pub_key) current_user.secret_key = fcrypt.generate_shared_dh_key( dh_pri_key, fcrypt.deserialize_pub_key(response_from_client.dh_pub_key)) # compose response message n1 = response_from_client.n1 n2 = fcrypt.generate_nonce(32) current_user.temp_nonce = n2 serialized_dh_pub_key = fcrypt.serialize_pub_key(dh_pub_key) response_to_client = pickle.dumps( AuthMsg('', '', '', '', serialized_dh_pub_key, '', '', n1, n2), pickle.HIGHEST_PROTOCOL) encrypted_response_to_client = fcrypt.asymmetric_encryption( current_user.rsa_pub_key, response_to_client) return True, encrypted_response_to_client
def start_connection(self, msg_received): tag = msg_received.tag iv_from_user = msg_received.iv ticket = fcrypt.symmetric_decryption(self.shared_dh_key, iv_from_user, tag, msg_received.ticket) ticket_signature = msg_received.ticket_signature if not fcrypt.verify_signature(self.server_pub_key, ticket, ticket_signature): return user_name_in_ticket, dh_pub_key_in_ticket, timestamp_to_expire = ticket.split(SPACE_SEPARATOR) if user_name_in_ticket != msg_received.user_name or float(timestamp_to_expire) < time.time(): return received_from_user = UserInfo() received_from_user.address = (msg_received.ip, msg_received.port) received_from_user.public_key = fcrypt.deserialize_pub_key(msg_received.public_key) # received_from_user.sec_key = session_key_in_ticket received_from_user.sec_key = fcrypt.generate_shared_dh_key(self.dh_pri_key, fcrypt.deserialize_pub_key(dh_pub_key_in_ticket)) received_from_user.info_known = True self.online_list[msg_received.user_name] = received_from_user # send connection back message to the initiator n3 = msg_received.n3 received_from_user.n4 = fcrypt.generate_nonce() iv = base64.b64encode(os.urandom(16)) response_msg = ConnMsg( self.user_name, '', '', '', '', iv, fcrypt.symmetric_encryption(received_from_user.sec_key, iv, str(n3))[1], '', '', fcrypt.symmetric_encryption(received_from_user.sec_key, iv, str(n3))[0], received_from_user.n4, '', time.time() ) self.send_encrypted_data_to_client(received_from_user, MessageStatus.END_CONN, response_msg)
def start_authentication(self, solved_challenge, user_name, password): n1 = fcrypt.generate_nonce() send_msg = AuthMsg( solved_challenge, user_name, password, fcrypt.serialize_pub_key(self.rsa_pub_key), fcrypt.serialize_pub_key(self.dh_pub_key), self.client_ip, self.client_port, n1, '' ) msg_str = pickle.dumps(send_msg, pickle.HIGHEST_PROTOCOL) encrypted_msg = fcrypt.asymmetric_encryption(self.server_pub_key, msg_str) msg = dict() msg['type'] = MessageStatus.START_AUTH msg['data'] = encrypted_msg auth_start_msg = json.dumps(msg) self.client_sock.sendall(auth_start_msg) # Wait for Server response server_auth_response = self.client_sock.recv(MAX_BUFFER_SIZE) return n1, server_auth_response
def generate_challenge(self): challenge = fcrypt.generate_nonce() trunc_challenge = challenge & 0x0000ffffffffffffffffffffffffffff challenge_hash = fcrypt.generate_hash(str(challenge)) return challenge, challenge_hash, trunc_challenge