Написать программу для шифрования и расшифрования файла алгоритмом rc4 с размером блока 8 бит

Обновлено: 11.07.2024

Алгоритм RC4 разработан Р.Ривестом специально как генератор потока ключевой информации с ключом переменной длины. Генераторы псевдослучайных чисел , построенные с помощью таких алгоритмов, как RC4 , как правило, значительно быстрее генераторов, основанных на блочных шифрах. Алгоритм RC4 широко применяется в различных системах защиты информации, в компьютерных сетях (например, в протоколе SSL , для шифрования паролей в Windows NT, и др.). Алгоритм RC4 довольно прост и мы полностью рассмотрим принцип его действия.

RC4 — фактически класс алгоритмов, определяемых размером его блока или слова – параметром n . Обычно n = 8 , но можно использовать и другие значения. Для упрощения анализа алгоритма примем n=4 . Внутреннее состояние RC4 состоит из массива размером 2 n слов и двух счетчиков, каждый размером в одно слово . Два счетчика, оба при n=4 4-битовые, назовем i и j . Все вычисления проводятся по модулю 2 n .

Массив используется как таблица замен, называемая S-бокс, и далее будет обозначаться как S . В каждый момент времени таблица S содержит все возможные n-битовые (в нашем случае 4-битовые) числа в перемешанном виде. Конкретная перестановка значений в таблице определяется ключом. Так как каждый элемент таблицы принимает значения в промежутке 0 до 15 , то его можно трактовать двояко: либо как число, либо как номер другого элемента в таблице.

Алгоритм RC4 состоит из двух этапов. На первом, подготовительном этапе производится инициализация таблицы замен S . На втором, основном этапе вычисляются псевдослучайные числа.

Посмотрим, как инициализируется таблица S . Вначале она заполняется последовательно числами от 0 до 15 . Ключ представляется в виде последовательности 4-битовых слов, которыми заполняется другой массив K , такого же размера, как S . Если ключ оказался короче, чем надо, он повторяется нужное число раз. Затем выполняются следующие действия ( алгоритм 1 ):

В результате выполнения этого алгоритма производится начальное заполнение таблицы замен S , причем это начальное перемешивание значений производится в зависимости от секретного ключа.

После того, как таблица S подготовлена, можно начинать генерацию случайных n-битовых слов. Для этого счетчикам i и j присваивается начальное значение 0 . Затем для получения каждого нового значения zi выполняются следующие действия ( алгоритм 2 ):

Полученное 4-битовое значение zi может использоваться в качестве ключа для шифрования очередного 4-битового блока входного потока данных.

Например, пусть секретный ключ состоит из шести 4-битовых значений (приведем их в десятичном виде): 1, 2, 3, 4, 5, 6 . Попробуем сгенерировать последовательность чисел по алгоритму RC4 .

Заполним таблицу S последовательно числами от 0 до 15 .

Затем подготовим таблицу K , записав в нее ключ необходимое количество раз:

Затем перемешаем содержимое таблицы S . Для этого будем использовать алгоритм 1, описанный выше. Процесс выполнения представим в виде трассировочной таблицы ( таблица 8.2), в которой укажем все производимые действия. При выполнении вычислений необходимо помнить, что все операции сложения выполняются по модулю 16.

После выполнения алгоритма 1 получим инициализированную и подготовленную к основному этапу таблицу S :

После того как таблица S подготовлена, можно начинать генерацию случайных 4-битовых слов. Вычислим первые 5 чисел псевдослучайной последовательности, используя алгоритм 2. Результаты вычисления последовательности значений также представим в виде таблицы ( таблица 8.3)

RC4

Общие сведения о RC4

Итак, RC4 является потоковым шифром (stream cipher), что означает, что каждый символ открытого (незашифрованного) текста будет зашифрован в зависимости от двух параметров: ключа и положения символа в открытом тексте. В следующем разделе я поясню, как это работает.

Создал данный алгоритм шифрования профессор Массачусетского технологического института, Рональд Ривест, которому мы также обязаны такими алгоритмами, как RC2, RC5, RC6, RSA и линейкой хэшей MD2-MD6.

Несмотря на то, что вряд ли кто-то будет применять RC4 в новых ответственных проектах в связи с известными уязвимостями, существует целый ряд технологий которые его используют. Примерами таких технологий являются WEP, SSL, TLS. Также, в моем примере, его решили использовать и разработчики одной из MMORPG.

Алгоритм

Хочу, чтобы каждый мог понять, как работает RC4, потому буду объяснять на пальцах.

Итак, входными данными у нас будет выступать массив байт. Это может быть любая информация: голос, изображение, текст. Конечно, информация может поступать в виде потока, но что такое поток, если не длинный массив?
Какое же шифрование без ключа!? Ключ тоже выступает в качестве входных данных. Для алгоритма RC4 он может быть от 8 до 2048 бит, но обычно используется диапазон 40 — 256 бит.
Но данные для шифрования у нас — массив байт, а ключ почему-то в битах. Дело в том, что существует такое понятие как размер блока n. Для примера мы будем использовать n=8, но алгоритм будет даже более криптостоек, если взять n=16. Тогда за один шаг будут шифроваться сразу 2 байта.

Принцип шифрования

Идеальным вариантом с точки зрения стойкости для потокового шифра, является размер ключа, сопоставимый с размером шифруемых данных. Тогда каждый бит открытого текста объединяется с соответствующим битом ключа посредством суммирования по модулю 2 (XOR), образуя зашифрованную последовательность. Для расшифровки требуется проделать ту же операцию еще раз на принимающей стороне.

При условии, что последовательность битов ключа выбирается произвольно и не имеет периодов, взломать шифр невозможно, но возникает проблема передачи длинного ключа. Поэтому на практике для генерации ключевого потока используется генератор псевдослучайных чисел на основе заданного ключа. То есть мы расширяем наш ключ до любого размера (динамически, во время обработки входных данных) и XOR'ом объединяем его с входными данными.

Для генерации ключевого потока шифр использует скрытое внутреннее состояние, состоящее из двух частей:
— Перестановки, содержащей все возможные байты от 0x00 до 0xFF (массив S).
— Переменных-счетчиков x и y.

Для начальной инициализация вектора-перестановки ключём, используется алгоритм ключевого расписания (Key-Scheduling Algorithm):

private void init( byte [] key)
int keyLength = key.Length;

for ( int i = 0; i < 256; i++)
S[i] = ( byte )i;
>

int j = 0;
for ( int i = 0; i < 256; i++)
j = (j + S[i] + key[i % keyLength]) % 256;
S.Swap(i, j);
>
>


С точки зрения кода, ничего сложного. Хочу только отметить, что метод Swap (поменять два элемента массива местами) расширяет стандартный список методов класса Array:
static class SwapExt
public static void Swap( this T[] array, int index1, int index2)
T temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
>
>

Метод init нужно вызвать перед шифровкой/расшифровкой, когда известен ключ. Можно сделать это в конструкторе:

Дальше нужно реализовать генератор псевдослучайной последовательности (Pseudo-Random Generation Algorithm). При каждом вызове метод будет выплевывать последующий байт ключевого потока, который мы и будем объединять xor'ом c байтом исходных данных.

private byte keyItem()
x = (x + 1) % 256;
y = (y + S[x]) % 256;


Теперь осталось самое простое! Для каждого байта массива/потока входных незашифрованных данных запрашиваем байт ключа и объединяем их при помощи xor (^):

public byte [] Encode( byte [] dataB, int size)
<
byte [] data = dataB.Take(size).ToArray();

byte [] cipher = new byte [data.Length];

for ( int m = 0; m < data.Length; m++)
<
cipher[m] = ( byte )(data[m] ^ keyItem());
>


Для расшифровки можно использовать этот же метод. Завернем его в отдельный метод для наглядности:
public byte [] Decode( byte [] dataB, int size)
return Encode(dataB, size);
>

byte [] key = ASCIIEncoding.ASCII.GetBytes( "Key" );

RC4 encoder = new RC4(key);
string testString = "Plaintext" ;
byte [] testBytes = ASCIIEncoding.ASCII.GetBytes(testString);
byte [] result = encoder.Encode(testBytes, testBytes.Length);

RC4 decoder = new RC4(key);
byte [] decryptedBytes = decoder.Decode(result, result.Length);
string decryptedString = ASCIIEncoding.ASCII.GetString(decryptedBytes);

Результат работы RC4

И вот результат, чтобы убедиться, что все правильно работает:

Реализацией класса, дешифрующего трафик, мы на шаг приблизились к разбору пакетов.

В заключение скажу, что данная реализация наиболее простая и очевидная. Ее можно усложнить, чтобы повысить стойкость ко взлому.

Создадим простой dub-проект с минимальными указаниями и отсутствием внешних зависимостей, назовем его simplecrypt. Далее, берем из исходников QtE5 файл qte5.d и переносим его в папку simplecrypt/source проекта.

simplecrypt

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

Теперь напишем обработчики нажатия кнопок, и прежде всего выбор файла для обработки нашим шифровальным приложением, а также выбор файла ключа:

Эти обработчики, помещенные в класс окна, просто получают путь до соответствующего файла и отображают его в нужное текстовое поле, предварительно защищенное от записи данных со стороны пользователя. Также, мы устанавливаем ограничение на расширение файла, разрешаем следующий набор: *.key, *.keyfile, *.rc4.

Таким образом, наш обработчик выглядит примерно так:

Остальные два обработчика на время оставим в покое, поскольку они потребуют уже подготовленного кода, который мы сейчас рассмотрим.

Прежде всего, напишем сам алгоритм RC4 (описание и механизм работы я приводить не буду, он есть в упомянутой мной книге или в википедии), реализуя его в виде такого класса:

Класс RC4 работает следующим образом: сначала создается объект класса, затем методом adjustKey устанавливается 256-байтный ключ (задается в виде массива байтов), а затем по необходимости, методом encrypt шифруется или дешифруется набор байтов или строка. Стоит заметить, что метода обратного encrypt нет и расшифровывание файла выполняется с помощью того же самого метода encrypt на вход которому подается зашифрованный блок (а по необходимости повторяется процедура установки ключа). Сам класс RC4 мы помещаем в файл rc4.d.

Чтобы пойти дальше, нам потребуется принять тот факт, что исходный файл и файл ключа не должны быть изменены нашей программой, и что пользователь сам должен решить что делать с незашифрованным файлом. Понимаю, что это один из неразумных шагов с моей стороны, однако, я пока не знаю, как уничтожить исходный файл безопасным образом. Кроме того, неизменность обоих файлов в начале процесса обработки их через simplecrypt вполне надежная гарантия успешной работы алгоритма. Стало быть файлы должны быть read-only, т.е. доступны только для чтения.

Как видно из приведенного выше фрагмента кода, мы постарались учесть все возможные преграды на пути извлечения из файлов информации в виде байтового потока, снабдив наш класс блоками генерации исключительных ситуаций с подробной информацией о возникших проблемах.

Теперь можно описать процедуру, которая применяет алгоритм RC4 к некоторому файлу:

Нетрудно заметить, что предприняты меры предосторожности на случай некорректных данных, а также специально введено замедление процесса для того, чтобы отобразить информацию о ходе процесса шифрования.

Например, однажды мне почти удалось зашифровать саму программу шифровальщик, что привело к весьма занятным результатам и выводам: при попытке запуска программы с включенным антивирусом можно получить блокировку приложения, т.к. как антивирус считает, что у нас в системе запущен полиморфный вирус.

На этом прекрасном моменте, я заканчиваю свой рассказ и прилагаю к этой статье полный код всего проекта с примерами сгенерированных ключей.

В криптографии RC4 (сокращение от Rivest Cipher 4) представляет собой алгоритм потокового шифрования с переменной длиной ключа. Он использует один и тот же ключ для шифрования и дешифрования, поэтому он также принадлежит к симметричному алгоритму шифрования. RC4 - это алгоритм шифрования, используемый в Wired Equivalent Encryption (WEP), и когда-то он был одним из алгоритмов, которые может использовать TLS.

Серийный шифр RC4 - это последовательный шифр, разработанный американской компанией RSA Data Security. Фактически, компания не объявила о деталях конструкции алгоритма RC4 в начале. После того, как люди получили алгоритм посредством обратного анализа, компания RSA анонсировала алгоритм шифрования RC4 в 1997 году.
Преимущество алгоритма RC4 состоит в том, что алгоритм прост, эффективен и подходит для реализации программного обеспечения.

RC4 алгоритм шифрования и дешифрования

Шифрование и дешифрование RC4 эквивалентно операции инволюции, поэтому, если ключи ввода одинаковы, одну и ту же операцию можно выполнять для шифрования и дешифрования данных.
И RC4 отличается от последовательного шифра на основе регистра. Это последовательный шифр, основанный на преобразовании таблицы нелинейных данных. Он основан на достаточно большой таблице данных, чтобы вносить нелинейные изменения в таблицу. , В результате чего нелинейная последовательность клавиш.
Основной процесс выглядит следующим образом:
Сначала RC4 берет 256-байтовую таблицу S и вводит 256-байтовую вспомогательную таблицу R

Заполните таблицу S линейно
означает инициализацию таблицы S, с другой стороны, S [n] = n; (0 <= n <= 255)

Заполните таблицу R. ключом начального значения. Если длина ключа начального значения меньше длины таблицы R (256), повторяйте последовательность заполнения до тех пор, пока таблица R не будет заполнена.
На самом деле недостатки повторного заполнения последовательности очень очевидны:

Например, пользователь вводит ключ a, затем все a в таблицу R после повторного заполнения
И пользователь вводит ключ aa, тогда таблица R после повторного заполнения становится все
Это явно не хороший результат

Другой способ - заполнение, то есть если длина ключа меньше длины таблицы R, заполнение в фиксированном формате используется для заполнения оставшейся части.

Перемешать список S со списком R
Алгоритм работы следующий:
①J = 0;
②Для I = 0: 255
J = J + S[i] + R[j] mod 256;
swap (S [i], S [j]); // Обмен S [i] и S [j]
Реализация кода:

Основные функции шифрования и дешифрования
После генерации рандомизированной S-таблицы вы можете выполнять алгоритмы шифрования или дешифрования данных.
RC4 можно рассматривать как автомат конечных состояний во время шифрования и дешифрования, который генерирует байты ключа путем непрерывной генерации новых состояний.
Следующая функция состояния RC4 определяется следующим образом:
①I = 0, J = 0; // состояние инициализации
②I = I + 1 mod 256;
③J = J + S[i] mod 256
ap swap (S [i], S [j]); // поменять местами S [i] и S [j]
И функция вывода RC4 определяется как:
①h = S[i] + S[j] mod 256;
②k = S[h];
Выход k выходной функции является сгенерированным байтом ключа. Пусть автоматы RC4 по конечному состоянию запускаются один за другим для вывода последовательности байтов ключа.

При шифровании добавьте байт ключа k и байт открытого текста по модулю два для завершения шифрования, а при расшифровке добавьте байт k ключа и байт зашифрованного текста по модулю два для завершения дешифрования.

подводить итоги

Посредством вышеописанного процесса алгоритм RC4 в основном завершен, и мы немного обработали некоторые функции и процессы, такие как чтение размера файла и удовлетворение процесса управления пользовательским шифрованием и дешифрованием.
Последнее небольшое демо выглядит следующим образом:

Читайте также: