Після встановлення зв'язку через центральний сервер Extra Systems Cypher Net із програмою output, програма input генерує випадковий сеансовий ключ та шифрує його через RSA відкритим ключем абонента, з яким ведуться переговори. Потім input висилає йому це шифрування, і відразу після цього висилає хеш згенерованого ключа. Аналогічні події відбуваються на іншому кінці зв'язку у програмі output.
Отримавши від партнера зазначену інформацію, input розшифровує сеансовий ключ своїм закритим ключем RSA та перевіряє збіг хешу. Потім обидва учасники зв'язку (input і output) складають по модулю два згенеровані ними випадкові послідовності (цим займається процедура make_common_key) і, зважаючи на комутативності цієї операції, отримують одне і те значення, яке і використовується далі як сеансовий ключ. Всі ці дії виконує процедура get_common_key, яка однакова і в приймачі, і передавачі.
Процедура узгодження ключових сеансів get_common_key виконує свою роботу за допомогою такого алгоритму:
int get_common_key(int socket) { char local_hash[HASH_SIZE], remote_hash1[HASH_SIZE], remote_hash2[HASH_SIZE]; char socket_buffer[PACKED_VALUE_LENTH + HASH_SIZE]; time_t start_time, end_time; init_hash(); printf("Создаем защищенный канал связи...\n"); make_local_key(); get_hash(local_key.packed, PACKED_VALUE_LENTH / 2, local_hash); time(&start_time); printf("Шифруем свою половину ключа...\n"); encrypt_local_key(); memcpy(socket_buffer, crypted_local_key, PACKED_VALUE_LENTH); memcpy(socket_buffer + PACKED_VALUE_LENTH, local_hash, HASH_SIZE); socket_send_buffer(socket, socket_buffer, PACKED_VALUE_LENTH + HASH_SIZE); if (socket_read_buffer(socket, socket_buffer, PACKED_VALUE_LENTH + HASH_SIZE) != (PACKED_VALUE_LENTH + HASH_SIZE)) return 0; memcpy(crypted_remote_key, socket_buffer, PACKED_VALUE_LENTH); memcpy(remote_hash1, socket_buffer + PACKED_VALUE_LENTH, HASH_SIZE); printf("Дешифруем чужую половину ключа...\n"); decrypt_remote_key(); time(&end_time); get_hash(remote_key.packed, PACKED_VALUE_LENTH / 2, remote_hash2); if (memcmp(remote_hash1, remote_hash2, HASH_SIZE) != 0) return 0; make_common_key(); printf("Канал связи создан за %ld сек.\n\n", (long int)(end_time - start_time)); return 1; }
Процедури шифрування та розшифрування сеансового ключа encrypt_local_key та decrypt_remote_key описані тут.
Характерною особливістю цієї процедури є повна готовність використовувати ключі RSA будь-якого розміру та алгоритми хешування будь-якого типу. З цією метою формується буфер розміром PACKED_VALUE_LENTH + HASH_SIZE, розмір якого (змінна socket_buffer_size) пересилається в першу чергу. Це потрібно для того, щоб сервер, прочитавши це значення, знав, якого саме розміру пересилання між абонентами слід здійснити (процедура connect_server).
Контент цієї сторінки доступний також англійською, французькою, німецькою та російською мовами.
© Extra Systems, 2024 |