Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.12.2012, 10:48   #1
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию Чтение файла, шифрование Blowfish

Помогите пожалуйста, очень срочно.
Моя задача реализовать алгоритм шифрования Blowfish. Шифрование файлов/папок.

В переменные high, low подаётся информация по 32 бита (4 байта), я понимаю, что в чём проблема взять ф-цию fread и считывать, но как правильно это сделать, т.к. если у нас в конце получается остается меньше 4 байт информации мы должны заполнить недостающее место НУЛЯМИ, или другим заранее известным способом.
Помогите реализовать функцию которая к примеру будет открывать файл и считывать в эти переменные 4 байта.
И ещё один вопрос, я хочу зашифровать каталог с файлами и подкаталогами, всё это делаю при помощи FindFirstFile, FindNextFile (это я знаю), по идее я должен зашифрованный вариант записать в один файл, но как при расшифровки восстановить каталоги.

Код:
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
 
typedef struct _blowfish_ctx
{
    unsigned long P[18];
    unsigned long sbox[4][256];
}blowfish_ctx;
 
//Матрица
const unsigned int FIXED_S[4][256] = {
    {0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
    0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
   //....256 для экономии места
   }
    }; 
//Ключи
const unsigned long FIXED_P[] = {
    0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
    0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
    0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
    0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
    0x9216D5D9, 0x8979FB1B};
 
void swap(unsigned long *a, unsigned long *b)
{
    unsigned long temp;
 
    if(a && b)
        temp = *a, *a = *b, *b = temp;
}
 

unsigned long F(blowfish_ctx *S, unsigned long x)
{
    return ((S->sbox[0][(x >> 24) & 0xFF] + S->sbox[1][(x >> 16) & 0xFF]) ^ S->sbox[2][(x >> 8) & 0xFF]) + S->sbox[3][(x) & 0xFF];
}
 
void blowfish_decrypt_block(blowfish_ctx *ctx, unsigned long *high, unsigned long *low)
{
    int i;
 
    for(i = 17; i > 1; i--)
    {
        *high ^= ctx->P[i];
        *low ^= F(ctx, *high);
        swap(low, high);
    }
 
    swap(low, high);
    *high ^= ctx->P[0];
    *low ^= ctx->P[1];
}
 
//Шифрование
void blowfish_encrypt_block(blowfish_ctx *ctx, unsigned long *high, unsigned long *low)//high,low - 
{                                                                                      //левый и правый блоки
    int i;
 
    for(i = 0; i < 16; i++) //шифрование 16 раундов
    {
        *high ^= ctx->P[i];     //XOR-им high с кючами P[i]
        *low ^= F(ctx, *high);  //XOR low и F(x)
        swap(low, high);        //Меняем местами
    }
 
    swap(low, high);
    *low ^= ctx->P[16];       
    *high ^= ctx->P[17];       
}
 
int blowfish_init(blowfish_ctx *ctx, unsigned char *key, size_t key_len)
{
    int i, j;
    unsigned long k, l;
    unsigned long long_key;
 
    if(ctx && key && key_len > 0 && key_len <= 56)
    {
        memcpy(ctx->P, FIXED_P, 18 * sizeof(FIXED_P));
 
        for(i = 0; i < 4; i++)
            memcpy(ctx->sbox[i], FIXED_S[i], sizeof(FIXED_S[i]));
 
        for(i = 0, k = 0; i < 18; i++)
        {
           for(j = 0, long_key = 0; j < 4; j++, k++)
                long_key = (long_key << 8) | key[k % key_len];
            ctx->P[i] ^= long_key;
        }
 
        for(i = 0, k = 0, l = 0; i < 18; i++)
        {
            blowfish_encrypt_block(ctx, &k, &l);
            ctx->P[i] = k;
            ctx->P[++i] = l;
        }
 
        for(i = 0; i < 4; i++)
        {
            for(j = 0; j < 256; j++)
            {
                blowfish_encrypt_block(ctx, &k, &l);
                ctx->sbox[i][j] = k;
                ctx->sbox[i][++j] = l;
            }
        }
        return 0;
    }
 
    return -1;
}
 
int SeachFile(char *file)
{
    char buffer[5] = "";
 
    FILE *f = fopen(file, "r");
 
    if(f == NULL)
        return 0;
 
    while(feof(f) == 0)
    {
        fread(&buffer, 4, 1, f);        
        printf("%s", buffer);
        fread(&buffer, 4, 1, f);
        printf("%s", buffer);
    }
 
    return 1;
}
 
int main(int argc, char **argv)
{
    setlocale(LC_ALL, "RU");
    blowfish_ctx *ctx = (blowfish_ctx *)malloc(sizeof(blowfish_ctx));
    unsigned long high = 1, low = 6556;
 
    if(!ctx)
    {
        puts("Insufficient memory allocated");
        return -1;
    }
 
    if(blowfish_init(ctx, (unsigned char *)"TESTKEY", 7) != 0)
    {
        free(ctx);
        puts("Key initialization failed");
        return -1;
    }
 
    SeachFile("blowfish.obj");
 
    blowfish_encrypt_block(ctx, &high, &low);
    printf("Шифрование: Верхний 32 bits:%08X Нижний 32 bits:%08X\n", high, low);
    blowfish_decrypt_block(ctx, &high, &low);
    printf("Дешифрование: Верхний 32 bits:%08X Нижний 32 bits:%08X\n", high, low);
    free(ctx);
 
    return 0;
}
в строке unsigned long high = 1, low = 6556; это пример шифрования значений 1 и 6556

Последний раз редактировалось Stilet; 20.12.2012 в 11:11.
ManHunterGroms вне форума Ответить с цитированием
Старый 20.12.2012, 11:23   #2
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Цитата:
И ещё один вопрос, я хочу зашифровать каталог с файлами и подкаталогами, всё это делаю при помощи FindFirstFile, FindNextFile (это я знаю), по идее я должен зашифрованный вариант записать в один файл, но как при расшифровки восстановить каталоги.
По сути, это задача "как превратить каталог с подкаталогами в один файл". Первое напрашивающееся решение - припахать архиватор, который это умеет (заодно он снизит информационную избыточность текста, что небесполезно). Второе - сделать "архиватор" самостоятельно: выделить отдельную фазу, переводящую каталог в файл определённого формата; скажем, последовательность записей вида "полный путь от шифруемого каталога - размер файла - содержимое файла"; при этом не обязательно даже "реально" этот файл создавать, но его формат рекомендуется явно описать в комментариях к программе.

Цитата:
Помогите реализовать функцию которая к примеру будет открывать файл и считывать в эти переменные 4 байта.
Обратите внимание на то, что возвращает вызов fread(). Сходу мне не удалось найти строгого описания поведения fread() при чтении неполного блока, так что принудительное забивание его байт нулями может оказаться излишней работой, но, ИМХО, стоит это сделать.
Интереснее то, что при расшифровывании также следует выделять ситуацию с "обрезанным" блоком: некоторые файловые форматы чувствительны к тому, чем заканчивается файл, и добавление пары нулевых байтов в конец может их "испортить".
Abstraction вне форума Ответить с цитированием
Старый 22.12.2012, 19:33   #3
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию

Спасибо за ответ.
Для начала я пишу ф-цю открытия файла для чтения и шифрования/дешифрования, но столкнулся с проблемой преобразования unsigned long в char, пишу на чистом СИ поэтому С++ функции использовать нельзя. Вот код:
Код:
int operateFile(char *file, char *file2, char mode)//1: файл который шифрую 2: в который записываю 3: режим расшифровка/зашифровка
{
	unsigned long buffer;
	byte flag = 1;//флаг для определения в который блок читаем 4 байта

	FILE *f  = fopen(file, "r");
	FILE *f2 = fopen(file2, "w");

	if(f == NULL || f2 == NULL)
	{
		printf("ERROR open file!!!\n");
		return 0;
	}

	switch(mode)
	{
		case 'e'://режим шифрования
			while(fread(&buffer, 4, 1, f) == 1)//читаем по 4 байта
			{					
				if(flag == 1)
				{
					high = buffer;
					flag = 2;						
				}
				else
				{							
					low = buffer;			
					flag = 1;
					blowfish_encrypt_block(ctx, &high, &low);//шифрую
					fprintf(f2, "%08x%08x", high, low);	//записываю в файл
				}		
			}
			break;

		case 'd'://режим дешифрования
			while(fscanf(f, "%08x", &buffer) != EOF)//пока не конец файла, читаю
			{	
				if(flag == 1)
				{
					high = buffer;
					flag = 2;	
				}
				else
				{							
					low = buffer;			
					flag = 1;					
					blowfish_decrypt_block(ctx, &high, &low);//расшифровываю
					fprintf(f2, "%08x%08x", high, low);		//записываю в файл			
				}		
			}
			break;

		default:
			printf("ERROR Work-Mode!!!\n");
			return 0;
	}

	/* Заполнение нулями. Будет реализовано позже
	if(flag == 2)
	{
		low = 00000000;
	}
	*/

	fclose(f);
	fclose(f2);

	return 1;
}
вот в этой части нужно вставить ф-цию преобразования unsigned long->char и записывать в файл уже переведенный тескт:
Код:
blowfish_decrypt_block(ctx, &high, &low);//расшифровываю
fprintf(f2, "%08x%08x", high, low);		//записываю в файл
ManHunterGroms вне форума Ответить с цитированием
Старый 23.12.2012, 23:36   #4
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию

У меня получается, что после расшифровки я записываю значения в шестнадцатеричной системе!
Как мне реализовать перевод? я в ступоре из-за какой-то ерунды, а задание уже сдавать нужно, спросить неукого
ManHunterGroms вне форума Ответить с цитированием
Старый 23.12.2012, 23:53   #5
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

что бы получить 16 разрядное число типо 128.
128 * 255;
16 разрядное может содержать 65535
если разделить макс 65535... на 255, мы получим 256
//-----
8 разрядное... байт иначе 255 макс
16 разрядное 2 байта 655535 макс
32 разрядное 4 байта 4294967295 макс
//-----
я говорю только о положительных числах...
со знаком в половину меньше.
//-----
а так если у тебя число ввиде текста попробуй atoi потом itoa, только укажи 10 систему
не знаю прокатит ли... а так есть множество в инете реализаций IntToHex HexToInt
раз
два
Если помог, тут весы есть , Вам не сложно, а мне приятно.

Последний раз редактировалось Perchik71; 24.12.2012 в 00:05.
Perchik71 вне форума Ответить с цитированием
Старый 24.12.2012, 19:06   #6
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию

Помогите пожалуйста. Днями ломаю голову, вообщем сделал я перевод из hextoint но мне это не помогло.
У меня есть текстовый файл с текстом: Hello World. После шифрации он принимает вид: baae65f031fb1b3c, после расшифровывания: 6c6c65486f57206f.
По идее первые 2 символа равны первому символа исходного текста 6с = H, я перевёл 6с из 16-ричной системы и получил 108, я посчитал что 108 это будет моим ASCII-кодом, но ошибся 108 это l.
Помогите, я уже 2-й день сижу за программой и все идеи которые приходят в голову не проходят. Может кто-то уже делал шифрование файла и может подсказать, что мне делать.
Ещё раз повторюсь, спросить неукого исходного текста других работ я не нашёл, а мне кроме этого ещё нужно сделать шифрование каталогов, что без шифрования файлов я не могу сделать. Последняя надежда на форум...

Весь исходный код не могу выложить в комментарии, поэтому залил на гугл драйв:
https://docs.google.com/folder/d/0B_...tqMVRONWs/edit

Последний раз редактировалось ManHunterGroms; 24.12.2012 в 19:09.
ManHunterGroms вне форума Ответить с цитированием
Старый 24.12.2012, 21:38   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

На вашем месте я бы начал без шифрования - сделал бы чтоб blowfish_encrypt_block / blowfish_decrypt_block просто копировали блок данных. Это поможет вам разобраться с чтением/записью файла.
waleri вне форума Ответить с цитированием
Старый 24.12.2012, 21:54   #8
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
На вашем месте я бы начал без шифрования - сделал бы чтоб blowfish_encrypt_block / blowfish_decrypt_block просто копировали блок данных. Это поможет вам разобраться с чтением/записью файла.
Что вы имеете ввиду под копирование блок данных? я просто не понимаю как это поможет с записью файла.
ManHunterGroms вне форума Ответить с цитированием
Старый 25.12.2012, 07:59   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Хорошо, зайдем с другой стороны. Вам не кажется странным, что вы пишете зашифрованный файл с помощью fprintf а читаете его через fread?

У вас на входе в fprintf есть какието данные, которые преобразуются и записываются в файл. Вам надо сделать обратное преобразование. Задайте себе вопрос что делает fprintf (в вашем случае) и как сделать то же самое без fprintf а через fwrite и найдете ответ.
waleri вне форума Ответить с цитированием
Старый 25.12.2012, 17:58   #10
ManHunterGroms
Пользователь
 
Регистрация: 15.12.2011
Сообщений: 11
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Хорошо, зайдем с другой стороны. Вам не кажется странным, что вы пишете зашифрованный файл с помощью fprintf а читаете его через fread?

У вас на входе в fprintf есть какието данные, которые преобразуются и записываются в файл. Вам надо сделать обратное преобразование. Задайте себе вопрос что делает fprintf (в вашем случае) и как сделать то же самое без fprintf а через fwrite и найдете ответ.
СПАСИБО ВАМ ОГРОМНОЕ. Я понял свою ошибку!!! Вы меня спасли!
ManHunterGroms вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шифрование файла by_Trojan C# (си шарп) 2 07.04.2012 20:28
шифрование файла (Assembler) phantom4eg Помощь студентам 2 10.04.2010 16:36
Шифрование файла. dip Помощь студентам 1 04.12.2009 10:17
шифрование и дешифрование файла Анастасия123456789 Помощь студентам 1 05.05.2009 15:47
Реализация BlowFish на Delphi Unconnected Общие вопросы Delphi 2 19.02.2009 12:52