Der Empfänger (input) dient dazu, Informationen vom Teilnehmer zu empfangen, mit dem Verhandlungen geführt werden, und die empfangenen Informationen auf dem Konsolenbildschirm anzuzeigen. Zu Beginn der Sitzung fragt der Empfänger den Benutzer nach seiner Kennung sowie nach der Kennung des Teilnehmers, von dem Textinformationen empfangen werden. Der Empfänger muss über den privaten Schlüssel des Abonnenten verfügen, der ihn verwendet, und über den öffentlichen Schlüssel des Abonnenten, mit dem Verhandlungen geführt werden. Ein entsprechender Fingerabdruck muss ebenfalls vorhanden sein.
Das Senden des entsprechenden Fingerabdrucks an den Server (dadurch identifiziert der Server den Client und bestimmt, welchem Abonnenten er zugeordnet werden muss) erfolgt durch die Prozedur send_finger_print.
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. Anschließend addieren beide Kommunikationsteilnehmer (Eingang und Ausgang) die von ihnen erzeugten Zufallsfolgen modulo zwei 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.
Sobald der Sitzungsschlüssel auf diese Weise generiert wurde, kommt das Stream-Verschlüsselungsmodul ins Spiel. Es exportiert die generischen Funktionen (kapselt die erforderlichen Operationen unabhängig vom gewählten Stream-Verschlüsselungsalgorithmus) make_crypt_key_table (erstellt eine Schlüsseltabelle), encrypt_buffer (verschlüsselt den Puffer im Eingabeprogramm) und decrypt_buffer (entschlüsselt den Puffer im Ausgabeprogramm).
Das Eingabeprogramm erledigt seine Aufgabe mit diesem Algorithmus:
#include "common.h" #define STR_BUF_SIZE 4096 #define CLIENT_MODE CLIENT_MODE_INPUT int main(void) { int my_id, his_id, my_socket, buf_size, client_mode = CLIENT_MODE; char str_buf[STR_BUF_SIZE]; char public_name[64], private_name[64]; set_console_code_page(); printf ("\nКлиент консольной шифросвязи (приемник)\n(C) Extra Systems, 2024\n\n"); printf ("Укажите свой идентификатор: "); scanf("%d", &my_id); printf ("Укажите идентификатор партнера: "); scanf("%d", &his_id); printf ("\n"); sprintf(private_name, "private_%d", my_id); sprintf(public_name, "public_%d", his_id); if (!load_rsa_keys(public_name, private_name)) { printf("На диске отсутствуют нужные ключи...\n\n"); return 1; } print_crypt_params(); sockets_startup(); my_socket = create_client_socket(main_server_name, main_server_port); if (!send_finger_print(my_socket, my_id, his_id, CLIENT_MODE)) { printf("На диске отсутствует нужный fingerprint...\n\n"); return 1; } if (!get_common_key(my_socket)) { printf("Канал связи установить не удалось...\n"); return 1; } make_crypt_key_table(); while (buf_size = socket_read_buffer(my_socket, str_buf, STR_BUF_SIZE)) { str_buf[buf_size] = 0; decrypt_buffer(str_buf, buf_size); printf( "%s", str_buf); } close_socket(my_socket); sockets_cleanup(); return 0; }
Der Inhalt dieser Seite ist auch in Englisch, Französisch, Portugiesisch, Spanisch, Italienisch, Ukrainisch und Russisch verfügbar.
© Extra Systems, 2024 |
|