Extra Systems

CYPHERNET

procedimento de negociação de chaves de sessão


Após estabelecer uma ligação através do servidor central Extra Systems Cypher Net com o programa de saída, o programa de entrada gera uma chave de sessão aleatória e encripta-a via RSA com a chave pública do assinante com quem as negociações estão a ser conduzidas. De seguida, input envia-lhe essa encriptação e imediatamente em seguida envia o hash da chave gerada. Eventos semelhantes ocorrem na outra extremidade da ligação no programa de saída.

Tendo recebido as informações especificadas do parceiro, a entrada desencripta a chave de sessão com a sua chave privada RSA e verifica a correspondência de hash. De seguida, ambos os participantes do módulo de comunicação (entrada e saída) somam as sequências aleatórias que geraram (isto é feito pelo procedimento make_common_key) e, devido à comutabilidade desta operação, obtêm o mesmo valor, que é depois utilizado como chave de sessão. Todas estas ações são realizadas pelo procedimento get_common_key, que é o mesmo tanto no recetor como no transmissor.

O procedimento de negociação da chave de sessão get_common_key faz o seu trabalho utilizando o seguinte algoritmo:

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;
}

Os procedimentos de encriptação e desencriptação das chaves de sessão encrypt_local_key e decrypt_remote_key são aqui descritos.

Uma característica deste procedimento é a sua total disponibilidade para utilizar chaves RSA de qualquer tamanho e algoritmos hash de qualquer tipo. Para tal, é formado um buffer de tamanho PACKED_VALUE_LENTH + HASH_SIZE, cujo tamanho (variável socket_buffer_size) é enviado em primeiro lugar. Isto é necessário para que o servidor, ao ler este valor, saiba exatamente qual o tamanho da transferência entre assinantes que deve realizar (procedimento connect_server).

O conteúdo desta página está também disponível em inglês, francês, alemão, espanhol, ucraniano e russo.


© Extra Systems, 2024 Extra Web Top