Extra Systems

CYPHERNET

консольная система надежной коммерческой шифросвязи через сеть интернет

модуль перетасовки алфавита


Модуль перетасовки алфавита предназначен для дополнительной защиты передаваемой по каналу связи секретной информации. Хотя применяемое нами в Extra Systems Cypher Net потоковое шифрование RC4 и не имеет в нашей реализации никаких уязвимостей, тем не менее сохраняется теоретическая возможность перебора ключей с последующим лексическим анализом попыток расшифровки передаваемой информации. Речь, конечно, не идет о тех возможностях, которыми человечество располагает сегодня. Для современных систем время перебора ключей RC4 в нашем случае на много порядков превышает время существования Вселенной. Речь идет о тех гипотетических возможностях, которые могут появиться в будущем. Имея намерение застраховаться от любых мыслимых вариантов, мы и добавили к Extra Systems Cypher Net данный модуль перетасовки алфавита, который делает в принципе невозможным лексический анализ попыток расшифровки, и таким образом лишает злоумышленника в принципе какой-либо возможности взломать данную систему шифрованной связи.

Суть этого метода заключается в том, что коды 256 символов (количество вариантов для одного байта из восьми бит) совершенно случайным образом перемещаются в таблице, так что текст на любом языке превращается в полную абракадабру, состоящую из печатных и непечатных символов, перемешанных между собой совершенно непредсказуемым образом. В результате этого метод взлома путем полного перебора паролей шифрования, суть которого заключается в поиске вариантов, когда шифротекст превращается в набор неких печатных символов, полностью теряет свою состоятельность, поскольку правильный пароль, при нашем подходе, который здесь описывается, превращается, как уже было указано, в абракадабру, которую никак не возможно принять за нормальный текст.

Таким образом, взломщик Extra Systems Cypher Net не имеет возможности подбирать пароль, ориентируясь на то, чтобы получить некий осмысленный текст.

Изначально в системе создается таблица, которая соответствует тождественному преобразованию (то есть, она ничего не делает - не меняет информацию о кодировке символов). Это делает модуль shuffle_init:

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

Затем информация в этой таблице случайным образом тасуется (данную процедуру можно, и даже нужно, делать не один раз). Этим занимается модуль 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;
}

Применением этого ключа в системе Extra Systems Cypher Net занимается модуль shuffle (обратите внимание, что shuffle_decrypt_data создается "на лету" на базе shuffle_encrypt_data сразу после ее загрузки - этот факт автоматически обеспечивает полную согласованность алгоритмов кодирования и декодирования передаваемой информации), код которого на языке C выглядит следующим образом:

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

Благодаря этой хаотической перестановке букв злоумышленник полностью лишается возможности анализировать текст, который получается у него при попытках расшифровки по методу перебора ключей. Файл "shuffle.encrypt" формируется для каждого клиента свой, и кроме того, каждый клиент, при желании, снабжается программой shuffle_randomize, с помощью которой он сам может произвести любое количество дополнительных перестановок в этом своем ключевом файле.

Назначение процедур shuffle_rotate_l и shuffle_rotate_r заключается в том, чтобы исключить регулярные повторения ключевых байт кодировки UTF8 (которые возникают при употреблении всех языков, кроме английского — и особенно это характерно для кириллицы) — поскольку это обстоятельство могло бы служить зацепкой для подбора ключа RC4 методом «грубой силы». Применение нами этих процедур в данном модуле полностью исключает в нашем продукте и такую опасность.

Аналогичную задачу решает процедура shuffle_swap — ее работа заключается в перестановке битов в соседних байтах по определенной маске (SHUFFLE_SWAP_STEP). Конкретный вид этой маски мы подбираем исходя из критерия достижения максимального уровня энтропии итоговой последовательности байт (предварительно зашифрованных данным модулем). Для разных языков нами используются различные маски. Эффективность их работы, как правило, превышает показатель 7.9 бит энтропии на один байт. Мы не публикуем конкретные значения этих битовых масок, поскольку это никак не влияет на криптографическую стойкость нашей системы. Такое наше решение не нарушает принцип Керкгоффса, поскольку коды алгоритмов нами здесь полностью опубликованы, а конкретные значения SHUFFLE_SWAP_STEP относятся не к кодам, а скорее — к ключевым данным, сохранять которые в секрете принцип Керкгоффса никому не запрещает.

Естественно, что у любой пары (или компании) абонентов, общающихся между собой через Extra Systems Cypher Net, файл "shuffle.encrypt" должен быть идентичным. Изначально абоненты получают эти файлы от нас, но, как уже отмечалось выше, могут и самостоятельно их создавать и дополнительно перетасовывать. Важно лишь, чтобы они в этом случае, для обеспечения идентичности всех комплектов, физически их передали своим партнерам (при личной встрече или через доверенного курьера).

Контент этой страницы доступен также на английском, французском, немецком, португальском, испанском, итальянском и украинском языке.


© Extra Systems, 2024 Extra Web Top