Після встановлення зв'язку через центральний сервер 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 |
|