Следует отметить, что сам механизм fingerprint, изобретенный нами в этой системе шифросвязи, служит одним из механизмов защиты центрального сервера от хакерских атак. Получая от абстрактного клиента (который может быть злоумышленником) запрос на соединение, сервер ожидает сразу же получить от него правильный fingerprint. Если этого не происходит, сервер не ведет с таким клиентом никаких дальнейших разговоров, и немедленно разрывает соединение. Напомним, что поскольку файлы fingerprint зашифрованы через RSA открытым (только по названию) ключом сервера, который на самом деле нигде не публикуется, подделать их совершенно невозможно.
Таким образом, с помощью такого простого механизма, мы и здесь имеем защиту, которую невозможно взломать.
Проверка валидности полученного сервером отпечатка fingerprint производится процедурой check_finger_print (которая вызывается на сервере в процедуре dispatch_call):
int check_finger_print(THREADDATA *thread_item) { unsigned char client_message[PACKED_VALUE_LENTH]; unsigned char encrypted_value[VALUE_LENTH], decrypted_value[VALUE_LENTH]; char local_hash[HARD_HASH_SIZE]; int my_socket; FINGERPRINT client_finger_print; my_socket = thread_item->thread_socket; if (socket_read_buffer(my_socket, client_message, PACKED_VALUE_LENTH) != PACKED_VALUE_LENTH) return 0; unpack_value(client_message, encrypted_value); long_power_mod(encrypted_value, decrypt_rsa_key.exponent, decrypt_rsa_key.modulus, decrypted_value); pack_value(decrypted_value, client_message); memcpy(&client_finger_print, client_message, sizeof(client_finger_print)); get_hard_hash(client_finger_print.mixed_item, sizeof(client_finger_print.mixed_item), local_hash); if (memcmp(client_finger_print.mixed_hash, local_hash, HARD_HASH_SIZE) != 0) return 0; get_fingerprint_items(&(thread_item->client_id), &(thread_item->server_id), &(thread_item->client_mode), &(thread_item->prolog_size), &client_finger_print); return 1; }
Кроме проверки валидности обратившегося клиента, check_finger_print, как легко видеть из данного кода, выполняют еще ряд подготовительных операций путем вызова процедуры get_fingerprint_items. С ее помощью из объекта fingerprint, имеющего структуру
typedef struct finger_print { unsigned char mixed_item[ITEM_SIZE * 2 * 3]; unsigned char mixed_hash[HARD_HASH_SIZE]; } FINGERPRINT;
в объект THREADDATA, имеющий структуру
typedef struct thread_data { int thread_id; int thread_socket; PEERID client_id; PEERID server_id; int server_thread; char *buffer_to_send; int buf_size; int prolog_size; unsigned char client_mode; } THREADDATA;
извлекаются идентификаторы абонентов (client_id и server_id), тип соединения (client_mode) и размер пролога (prolog_size). Все эти параметры, кстати говоря, совершенно необходимы для вызываемой на центральном сервере (в процедуре dispatch_call) сразу вслед за check_finger_print процедуре connect_server. Фактически, вся работа connect_server (как легко видно из ее кода) основана исключительно на этих четырех параметрах.
© Extra Systems, 2024 |