Gigaset Fortunes

20 февр. 2011 г.

RC4 максимально подробно.

Итак, те кто хочет почитать про крипто алгоритмы в принципе, могут залезть на вики, попинасть Романенкова Сашу, и сделать прочие нехорошие вещи. А конкретно в этом посте я на пальцах объясню как работает алгоритм шифрования RC4, так как я его понимаю.

Здесь я хотел написать длинную статью на тему как работет RC4, но внезапно натолкнулся на статью на хабре которая итак неплохо это делает, поэтому я просто напишу исходник на С =)
Статья тут: http://habrahabr.ru/blogs/crypto/111510/#habracut

Мы будем повсместно использовать макрос SWAP так что для начала обьявим его
#define SWAP(A,B) A=A^B; B=A^B; A=A^B;
Этот макросс всего лишь перестановка 2ух элементов.
http://en.wikipedia.org/wiki/XOR_swap_algorithm

А так же несколько глобальных переменных:
int i,j;
unsigned char S[255];

Начальная инициалзиция вектора-перестановки ключем.
Используется алгоритм ключевого расписания (Key-Scheduling Algorithm)
void RC4_Init(unsigned char* key)
{
 int keylen = strlen(key);
 for (i = 0; i < 256; i++) S[i] = i;    
 
 for (j = i = 0; i < 256; i++)
 {
  j = (j + key[i % keylen] + S[i]) % 256
  SWAP(S[i],S[j]);
 }
}
Эта функция должна вызыватся перед шифровокой\расшифровкой. Дальше нужно реализовать генератор псевдослучайной последовательности. При каждом вызове функция будет выплевывать последующий байт ключа, которым мы XOR-ом будем объеденять с байтом исходных данных
char RC4_NextKeyByte()
{
 i = (i + 1) % 256;
 j = (j + S[i]) % 256;
 SWAP(S[i],S[j]);
 return S[(S[i] + S[j]) % 256];
}
И наконец самое простое. Для каждого байта входных данных запрашиваем байт ключа и объеденяем их с помощью XOR. Учитывая что алгоритм симетричный то эту же функцию мы будем использовать для дешифровки.
char RC4_Crypt(char in)
{
 return in ^ RC4_NextKeyByte();
}
Вот вся программа:
#include <stdio.h>
#include <string.h>
#define SWAP(X,Y) X = X^Y; Y = X^Y; X = X^Y

int i,j;
unsigned char S[256];

void RC4_Init(unsigned char* key)
{
 int keylen = (int)strlen((char*)key);
 for (i = 0; i < 256; i++)S[i] = i;    
 
 for (j = i = 0; i < 256; i++)
 {
  j = (j + key[i % keylen] + S[i]) % 256;
  SWAP(S[i],S[j]);
 }
}

char RC4_NextKeyByte()
{
 i = (i + 1) % 256;
 j = (j + S[i]) % 256;
 SWAP(S[i],S[j]);
 return S[(S[i] + S[j]) % 256];
}

char RC4_Crypt(char in)
{
 return in ^ RC4_NextKeyByte();
}

int main(int argc, char* argv[])
{
 int x;
 unsigned char key[]  = "Key";
 char data[] = "Test data!"; 
 printf("%s\n",data);

 RC4_Init(key);
 for (x = 0; x < strlen(data); x++) {
  data[x] = RC4_Crypt(data[x]);
 }
 printf("%s\n",data);

 RC4_Init(key);
 for (x = 0; x < strlen(data); x++) {
  data[x] = RC4_Crypt(data[x]);
 } 
 printf("%s\n",data);

}

7 комментариев:

  1. Огромное спасибо!
    Очень помог!

    ОтветитьУдалить
  2. На 3 курсе этот код приниматься не будет.

    ОтветитьУдалить
  3. Лолд, Саш, а если я буду сдавать? =)

    ОтветитьУдалить
  4. Это другой разгвор.. Я покажу тебе почему я не буду принимть этот код. =)

    ОтветитьУдалить
  5. Хм, а у нас откровенное воровство не воспрещается?)))

    ОтветитьУдалить
  6. Для нас и делалось, какое воровство)

    ОтветитьУдалить
  7. А как же творческое переосмысление???? =)

    ОтветитьУдалить