Extra Systems

CYPHERNET

modulo di mescolamento dell'alfabeto


Il modulo di mescolamento alfabetico è progettato per una protezione aggiuntiva delle informazioni segrete trasmesse su un canale di comunicazione. Anche se la crittografia del flusso RC4 che utilizziamo in Extra Systems Cypher Net non presenta alcuna vulnerabilità nella nostra implementazione, rimane la possibilità teorica di enumerare le chiavi con successiva analisi lessicale dei tentativi di decrittografia delle informazioni trasmesse. Naturalmente non stiamo parlando delle opportunità che l’umanità ha oggi. Per i sistemi moderni, il tempo necessario per cercare le chiavi RC4 nel nostro caso è di molti ordini di grandezza più lungo della vita dell’Universo. Stiamo parlando di quelle ipotetiche possibilità che potrebbero apparire in futuro. Per proteggerci da qualsiasi possibilità immaginabile, abbiamo aggiunto a Extra Systems Cypher Net questo modulo di mescolamento alfabetico, che rende in linea di principio impossibile l'analisi lessicale dei tentativi di decrittazione e quindi priva l'aggressore di ogni possibilità di violare questo sistema di comunicazione crittografato.

L'essenza di questo metodo è che i codici di 256 caratteri (il numero di opzioni per un byte di otto bit) vengono spostati in modo completamente casuale nella tabella, in modo che il testo in qualsiasi lingua si trasformi in un completo senza senso, costituito da caratteri stampati e non stampabili mescolati insieme in modo completamente imprevedibile. Di conseguenza, il metodo di cracking mediante enumerazione forzata delle password di crittografia, la cui essenza è cercare opzioni quando il testo cifrato si trasforma in un insieme di determinati caratteri stampati, perde completamente la sua validità, poiché la password corretta, con il nostro approccio qui descritto, si trasforma, come già accennato, in abracadabra, che non può in alcun modo essere confuso con testo normale.

Pertanto, il cracker Extra Systems Cypher Net non è in grado di indovinare la password, concentrandosi sull'ottenimento di testo significativo.

Inizialmente, il sistema crea una tabella che corrisponde alla trasformazione dell'identità (ovvero, non fa nulla, non modifica le informazioni sulla codifica dei caratteri). Il modulo shuffle_init fa questo:

int main(void)
{
	int i,file_handle;
	unsigned char data[256];
	for (i=0; i<256; i++) data[i] = i;
	file_handle = creat("shuffle.encrypt", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	write(file_handle, data, sizeof(data));
	close(file_handle);
	return 0;
}

Quindi le informazioni in questa tabella vengono mescolate in modo casuale (questa procedura può, e anche dovrebbe, essere eseguita più di una volta). Questo viene fatto dal modulo shuffle_randomize:

int main(void)
{
	unsigned char src, dst;
	unsigned char shuffle_encrypt_data[256];
	unsigned char random_src[256], random_dst[256];
	int i, file_handle;
	file_handle = open("shuffle.encrypt", O_RDONLY);
	read(file_handle, shuffle_encrypt_data, sizeof(shuffle_encrypt_data));
	close(file_handle);
	fill_random_buffer(random_src, sizeof(random_src));
	fill_random_buffer(random_dst, sizeof(random_dst));
	for(i = 0; i < 256; i++)
	{
		src = shuffle_encrypt_data[random_src[i]];
		dst = shuffle_encrypt_data[random_dst[i]];
		shuffle_encrypt_data[random_src[i]] = dst;
		shuffle_encrypt_data[random_dst[i]] = src;
	}
	file_handle = creat("shuffle.encrypt", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	write(file_handle, shuffle_encrypt_data, sizeof(shuffle_encrypt_data));
	close(file_handle);
	return 0;
}

L'applicazione di questa chiave nel sistema Extra Systems Cypher Net è gestita dal modulo shuffle (da notare che shuffle_decrypt_data viene creato “al volo” sulla base di shuffle_encrypt_data immediatamente dopo il suo caricamento - questo fatto garantisce automaticamente la piena coerenza tra gli algoritmi di codifica e decodifica delle informazioni trasmesse), il cui codice in C è il seguente:

unsigned char shuffle_encrypt_data[256], shuffle_decrypt_data[256];

int load_shuffle_data(void)
{
	unsigned char src;
	int i, file_handle;
	if((file_handle = open("shuffle.encrypt", O_RDONLY)) == -1) return 0;
	read(file_handle, shuffle_encrypt_data, sizeof(shuffle_encrypt_data));
	close(file_handle);
	for(i = 0; i < 256; i++)
	{
		src = shuffle_encrypt_data[i];
		shuffle_decrypt_data[src] = i;
	}
	return 1;
}

void shuffle_rotate_l(unsigned char *buffer_ptr, int buffer_len)
{
	int i;
	unsigned char x;
	if (!buffer_len) return;
	x = buffer_ptr[0];
	for(i = 0; i < (buffer_len - 1); i++) buffer_ptr[i] = (buffer_ptr[i] << 4) | (buffer_ptr[i + 1] >> 4);
	buffer_ptr[buffer_len - 1] = (buffer_ptr[buffer_len - 1] << 4) | (x >> 4);
}

void shuffle_rotate_r(unsigned char *buffer_ptr, int buffer_len)
{
	int i;
	unsigned char x;
	if (!buffer_len) return;
	x = buffer_ptr[buffer_len - 1];
	for(i = (buffer_len - 1); i > 0; i--) buffer_ptr[i] = (buffer_ptr[i] >> 4) | (buffer_ptr[i - 1] << 4);
	buffer_ptr[0] = (buffer_ptr[0] >> 4) | (x << 4);
}

void shuffle_twist(unsigned char *buffer_ptr, int buffer_len)
{
	int i;
	unsigned char x, y;
	if (buffer_len < 2) return;
	for(i = 1; i < buffer_len; i++)
	{
		x = buffer_ptr[i - 1];
		y = buffer_ptr[i];
		buffer_ptr[i - 1] = (x & 0xF0) | (y >> 4);
		buffer_ptr[i] = (y & 0xF) | (x << 4);
	}
}

void shuffle_buffer(unsigned char *buffer_ptr, int buffer_len, unsigned char *shuffle_data)
{ 
	short counter;
	for(counter = 0; counter < buffer_len; counter++) buffer_ptr[counter] = shuffle_data[buffer_ptr[counter]];
}

void shuffle_swap_l(unsigned char *buffer_ptr, int buffer_len, unsigned char swap_old)
{
	int i;
	unsigned char x, y, swap_new;
	if (buffer_len < 2) return;
	swap_new = ~swap_old;
 	for(i = 1; i < buffer_len; i++)
	{
		x = buffer_ptr[i - 1];
		y = buffer_ptr[i];
		buffer_ptr[i - 1] = (x & swap_old) | (y & swap_new);
		buffer_ptr[i] = (y & swap_old) | (x & swap_new);
	}
}

void shuffle_swap_r(unsigned char *buffer_ptr, int buffer_len, unsigned char swap_old)
{
	int i;
	unsigned char x, y, swap_new;
	if (buffer_len < 2) return;
	swap_new = ~swap_old;
 	for(i = (buffer_len - 1); i > 0; i--)
	{
		x = buffer_ptr[i - 1];
		y = buffer_ptr[i];
		buffer_ptr[i - 1] = (x & swap_old) | (y & swap_new);
		buffer_ptr[i] = (y & swap_old) | (x & swap_new);
	}
}

void shuffle_encrypt_buffer(unsigned char *buffer_ptr, int buffer_len)
{
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_encrypt_data);
	shuffle_swap_l(buffer_ptr, buffer_len, SHUFFLE_SWAP_STEP_1);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_encrypt_data);
	shuffle_rotate_l(buffer_ptr, buffer_len);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_encrypt_data);
	shuffle_twist(buffer_ptr, buffer_len);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_encrypt_data);
	shuffle_swap_l(buffer_ptr, buffer_len, SHUFFLE_SWAP_STEP_2);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_encrypt_data);
}

void shuffle_decrypt_buffer(unsigned char *buffer_ptr, int buffer_len)
{
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_decrypt_data);
	shuffle_swap_r(buffer_ptr, buffer_len, SHUFFLE_SWAP_STEP_2);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_decrypt_data);
	shuffle_twist(buffer_ptr, buffer_len);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_decrypt_data);
	shuffle_rotate_r(buffer_ptr, buffer_len);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_decrypt_data);
	shuffle_swap_r(buffer_ptr, buffer_len, SHUFFLE_SWAP_STEP_1);
	shuffle_buffer(buffer_ptr, buffer_len, shuffle_decrypt_data);
}

Grazie a questa caotica riorganizzazione delle lettere, l'aggressore viene completamente privato della capacità di analizzare il testo che ottiene tentando di decifrarlo con il metodo della forza bruta. Il file "shuffle.encrypt" viene creato in modo diverso per ciascun client e inoltre ogni client, se lo desidera, è dotato del programma shuffle_randomize, con l'aiuto del quale può effettuare qualsiasi numero di permutazioni aggiuntive in questo file chiave.

Lo scopo delle procedure shuffle_rotate_l e shuffle_rotate_r è quello di eliminare le ripetizioni regolari dei byte della chiave della codifica UTF8 (che si verificano quando si utilizzano tutte le lingue tranne l'inglese - e questo è particolarmente tipico per l'alfabeto cirillico) - poiché questa circostanza potrebbe servire come indizio per selezionare la chiave RC4 utilizzando il metodo della "forza bruta". L'utilizzo di queste procedure in questo modulo elimina completamente tale pericolo nel nostro prodotto.

La procedura shuffle_swap risolve un problema simile: il suo compito è scambiare bit in byte adiacenti secondo una determinata maschera (SHUFFLE_SWAP_STEP). Selezioniamo il tipo specifico di questa maschera in base al criterio di raggiungimento del massimo livello di entropia della sequenza finale di byte (precedentemente crittografata da questo modulo). Usiamo maschere diverse per lingue diverse. La loro efficienza tipicamente supera i 7,9 bit di entropia per byte. Non pubblichiamo i valori specifici di queste maschere di bit, poiché ciò non influisce sulla forza crittografica del nostro sistema. Questa nostra decisione non viola il principio Kerkhoffs, poiché i codici degli algoritmi sono qui pubblicati integralmente, e i valori specifici di SHUFFLE_SWAP_STEP non si riferiscono a codici, ma piuttosto a dati chiave, che il principio Kerkhoffs non vieta a nessuno di mantenere segreti.

Naturalmente, qualsiasi coppia (o azienda) di abbonati che comunicano tra loro tramite Extra Systems Cypher Net deve avere un file "shuffle.encrypt" identico. Inizialmente, gli abbonati ricevono questi file da noi, ma, come notato sopra, possono crearli da soli e inoltre mescolarli. È importante solo che in questo caso, per garantire l'identità di tutti i set, li trasferiscano fisicamente ai loro partner (durante un incontro personale o tramite un corriere di fiducia).

Il contenuto di questa pagina è disponibile anche in inglese, francese, tedesco, portoghese, spagnolo, ucraino e russo.


© Extra Systems, 2024 Extra Web Top