Extra Systems

CYPHERNET

процедура узгодження сеансових ключів


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