Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Си] Зашифровать файл с помощью rc4, Помогите разобраться 
:(
    Опции темы
Weman
Дата 4.11.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.11.2005
Где: Санкт-Петрбург

Репутация: нет
Всего: нет



Здравствуйте, уважаемые! Прошу помощи. Передо мной стоит такая задача: необходимо с помощью алгоритма RC4 зашифровать некоторый файл (например jpeg-картинка) на языке Си. Нашел в Википедии сам алгоритм (здесь), вот его реализация (немного переделанная под себя):
Код

#include <stdio.h>
#include <conio.h>

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

/* KSA */
void rc4_init(unsigned char *key, unsigned int key_length)
{
    unsigned char temp;

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

    for (i=j=0;i<256;i++)
    {
    j=(j+S[i]+key[i % key_length])&255;

    temp=S[i];
    S[i]=S[j];
    S[j]=temp;
    }
    i=j=0;
}

/* PRGA */
unsigned char rc4_output() {
    unsigned char temp;

    i = (i + 1) & 255;
    j = (j + S[i]) & 255;

    temp=S[i];
    S[i]=S[j];
    S[j]=temp;

    return S[(S[i] + S[j]) & 255];
}

void main() {
    int k, output_length;
    unsigned char key[] = "Secret";     // key hardcoded to "Secret"

    output_length = 10;     // number of bytes of output desired

    rc4_init(key, 6);     // length of key is 6 in this case

    k = 0;
    while (k < output_length) {
      printf("%c", rc4_output());
      k++;
    }
}



Как я понимаю этот алгоритм - он состоит из 2х частей:
1. Создание ключа. Берется некое выражение, по которому будет создаваться ключ (в этом примере это выражение unsigned char key[] = "Secret";), считается его длина (6 символов) и передается в функцию rc4_init(key, 6);. В функции rc4_init происходит первоначальная инициализация массива 0..255 значениями от 0 до 255 и после происходит перемешивание этих значений в соответствии с входным выражением. Получаем массив символов, перемешанный неким образом.
2. Получение некоего выражения какой-то длины (в этом примере длины 10 - output_length = 10;), которое будет использоваться для шифрования исходного текста. В этом примере это зашифрованное выражение просто выводится на экран по-символьно с помощью цикла
Код
while (k < output_length) {
      printf("%c", rc4_output());
      k++;
    }


В общих чертах все примерно понятно как работает, но вернемся к моей задаче.
Мне необходимо реализовать программу следующим способом. У программы будут два входных файла -
1. Файл для шифрования (jpeg-картинка).
2. Секретный ключ-выражение (если я все правильно понял, то это аналог вот этой строки unsigned char key[] = "Secret";).

и будет один выходной файл - это результат работы программы - зашифрованная с помощью алгоритма rc4 картинка.

Теперь что я делаю:
1. Определяю константы с входными и выходными файлами
Код
#define FKEY "D:\\LR2\\key.txt\0" 
#define FIN  "D:\\LR2\\in.jpeg\0" 
#define FOUT "D:\\LR2\\out.enc\0"
 

2. Открываем файлы для чтения (файл с секретным ключом читаем как текстовый, а файлы с картинкой и выходной файл как бинарный, так необходимо читать побайтово).
    
Код
//Читаем файл с ключами а и b
    printf("Keys in file: %s\n", fkey);
    //Открываем файл в режиме чтение текста
    if((key=fopen(fkey,"rt"))==NULL)
    {
        //если не удалось прочитать, то выводим ошибку
        printf ("Error open file in read mode");
        getch();
        return -1;
    }

    //Открываем файл с входным зашифрованным текстом в режиме чтения бинарного
    printf("Input file: %s\n", fin);
    //Open file in mode read(r) text(t)
    if((in=fopen(fin,"r+b"))==NULL)
    {
        printf ("Error open file in read mode");
        getch();
        return -1;
    }

    //Открываем выходной файл для записи дешифрованного текста
    printf("Encrypted file: %s\n", fout);
    //Открываем файл в режиме записи бинарного
    if((out=fopen(fout,"w+b"))==NULL)
    {
        //если не удалось прочитать, то выводим ошибку
        printf ("Error open file in read mode");
        getch();
        return -1;
    }


3.Читаем из файла с секретом секретное слово и вычисляем его длину:
        
Код
unsigned char word[100] = "";     
    //Получаем ключ из key.txt
    //пока не нашли признак конца файла
    while (!feof(key))
        fgets(word,100,key);
    printf("%s\n",word);
    int len=strlen(word);
    printf("length line=%d\n\n",len);


4. Потом происходит инициализация массива и перемешивание в соответствии с секретным выражением. В функцию передаем наше слово и его длину:
        
Код
rc4_init(word, len);


5. Ну и теперь заключительный подготовительный этап. Необходимо получить некую последовательность, которая потом будет с помощью операции XOR (исключающее ИЛИ) складываться с исходной jpeg-картинкой и будет получаться зашифрованный поток по алгоритму rc4. Делаю так:
    
Код

    unsigned char gamma[10];

    unsigned char symbol;
    for (k=0;k<10;k++)
    {
    gamma[k]=rc4_output();
    }
    gamma[k]='\x0';


Получаю я вот эту строку, длинной 10 символов. И теперь мне надо как-то ее использовать, чтобы закодировать исходную последовательность. 

ВОПРОС: Если я исходный jpeg-файл буду читать побайтово, и для шифрования использоваться операцию XOR (исключающее ИЛИ), то как мне считанный байт складывать со строкой и что у меня должно получиться на выходе и что я в итоге должен буду записать в зашифрованный файл? 

Или может надо читать блоками по 256 байт и их обрабатывать и потом читать еще 256 и так далее...

Подскажите пожалуйста. Или может я неправильно понимаю принцип работы алгоритма и дальнейшего шифрования?...

P.S.:извините что так длинно получилось, но по другому не смог объяснить...
--------------------
PM MAIL ICQ   Вверх
bass
Дата 6.11.2010, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: нет
Всего: 2



А стандартный Winapi??????
Код


BOOL Kript(BYTE * Buffer,DWORD BufferLeght )
{
BYTE cript[0x1C] ={ //здесь ключ};
DWORD count2 =0x1c;//длина ключа
HCRYPTPROV hProv;
HCRYPTKEY hKey;
DWORD size = BufferLeght;

// Получение контекста криптопровайдера
if (!CryptAcquireContext(&hProv, NULL, NULL,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{return 0;}
if(!CryptImportKey(hProv, &cript[0], count2, 0, 0, &hKey))
{return 0;}
if (!CryptEncrypt(hKey, 0, true, 0, Buffer,&BufferLeght,size ))
{return 0;}
CryptReleaseContext(hProv,0);
return 1;
}


BOOL Deskript(BYTE * Buffer,DWORD BufferLeght )
{

BYTE cript[0x1C] ={};
DWORD count2 =0x1c;
HCRYPTPROV hProv;
HCRYPTKEY hKey;

//==================================расшифруем===================================

// Получение контекста криптопровайдера
if(!CryptAcquireContext(&hProv, NULL, NULL,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{return 0;}
if(!CryptImportKey(hProv,&cript[0], count2, 0, 0, &hKey))
{return 0;}
if(!CryptDecrypt(hKey, 0, true, 0, Buffer, &BufferLeght))
{return 0;}
CryptReleaseContext(hProv,0);

//============================================================================
return 1;
}


Добавлено через 4 минуты и 18 секунд
Ключ генерится с помощью функции winapi любой не подойдет и гугл в помощь ....... 
PM MAIL   Вверх
Weman
Дата 6.11.2010, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 29.11.2005
Где: Санкт-Петрбург

Репутация: нет
Всего: нет



Спасибо конечно за код, но для меня это очень сложно и даже непонятно что там делается.... :( Да и на языке Си надо.
--------------------
PM MAIL ICQ   Вверх
bass
Дата 6.11.2010, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: нет
Всего: 2



Что там сложного надеюсь под винду пишешь то это готовые функции зашифровки буфера а потом расшифровки...... Указатеть на буфер и длина буфера.... Ключек я убрал вселедствии использования в своей программе ... Могу сгенерить.....
PM MAIL   Вверх
xvr
Дата 8.11.2010, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



RC4 потоковый чипер (точнее, это генератор гаммы). Не надо брать 10 байтов из него для шифрования картинки, надо брать все:
Код

int sym;

while( (sym=fgetc(in)) != EOF)
{
 sym^=rc4_output();
 fputc(out,sym);
}
fclose(in);
fclose(out);


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0699 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.