After establishing a connection via the Extra Systems Cypher Net central server with the output program, the input program generates a random session key and encrypts it via RSA with the public key of the subscriber with whom the negotiations are being conducted. Then input sends him this encryption, and immediately after that sends the hash of the generated key. Similar events occur at the other end of the connection in the output program.
Having received the specified information from the partner, input decrypts the session key with its private RSA key and checks the hash match. Then both participants in the connection (input and output) add the two random sequences they generated modulo (this is done by the make_common_key procedure) and, due to the commutativity of this operation, they receive the same value, which is then used as a session key. All these actions are performed by the get_common_key procedure, which is the same in both the receiver and the transmitter.
The get_common_key session key negotiation procedure does its job using the following algorithm:
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; }
The procedures for encrypting and decrypting the session key encrypt_local_key and decrypt_remote_key are described here.
A characteristic feature of this procedure is its complete readiness to use RSA keys of any size and hashing algorithms of any type. For this purpose, a buffer of the size PACKED_VALUE_LENTH + HASH_SIZE is formed, the size of which (the socket_buffer_size variable) is sent first. This is necessary so that the server, having read this value, knows what size of transfer between subscribers it should perform (the connect_server procedure).
The content of this page is also available in French, German, Ukrainian and Russian.
© Extra Systems, 2024 |