Nach dem Verbindungsaufbau über den zentralen Extra Systems Cypher Net-Server mit dem Ausgabeprogramm generiert das Eingabeprogramm einen zufälligen Sitzungsschlüssel und verschlüsselt diesen per RSA mit dem öffentlichen Schlüssel des Teilnehmers, mit dem verhandelt wird. Dann sendet ihm Input diese Verschlüsselung und unmittelbar danach den Hash des generierten Schlüssels. Ähnliche Ereignisse treten am anderen Ende der Verbindung im Ausgabeprogramm auf.
Nachdem Input die angegebenen Informationen vom Partner erhalten hat, entschlüsselt er den Sitzungsschlüssel mit seinem privaten RSA-Schlüssel und prüft, ob eine Hash-Übereinstimmung vorliegt. Dann addieren beide Kommunikationsteilnehmer (Ein- und Ausgabe) modulo die von ihnen erzeugten Zufallssequenzen (dies geschieht durch die Prozedur make_common_key) und erhalten aufgrund der Kommutierbarkeit dieser Operation den gleichen Wert, der dann als Sitzungsschlüssel verwendet wird. Alle diese Aktionen werden von der Prozedur get_common_key ausgeführt, die sowohl im Empfänger als auch im Sender gleich ist.
Das Sitzungsschlüssel-Aushandlungsverfahren get_common_key erledigt seine Aufgabe mithilfe des folgenden Algorithmus:
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; }
Die Verschlüsselungs- und Entschlüsselungsverfahren für den Sitzungsschlüssel encrypt_local_key und decrypt_remote_key werden hier beschrieben.
Ein charakteristisches Merkmal dieses Verfahrens ist die vollständige Bereitschaft, RSA-Schlüssel beliebiger Größe und Hash-Algorithmen jeglicher Art zu verwenden. Hierzu wird ein Puffer der Größe PACKED_VALUE_LENTH + HASH_SIZE gebildet, dessen Größe (Variable socket_buffer_size) zuerst gesendet wird. Dies ist notwendig, damit der Server nach dem Lesen dieses Werts genau weiß, welche Größenübertragung zwischen Teilnehmern er durchführen soll (die Prozedur connect_server).
Der Inhalt dieser Seite ist auch in Englisch, Französisch, Ukrainisch und Russisch verfügbar.
© Extra Systems, 2024 |