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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.05.2018, 18:41   #1
Anton_Jag
Пользователь
 
Регистрация: 05.11.2009
Сообщений: 41
По умолчанию Шифрование vmpc

Пытаюсь зашифровать данные из кольцевого списка, записать их в бинарный файл, затем считать и расшифровать. Функцию шифрования vmpc нашел в инете.
При пошаговом выполнении функции записи в файл происходит шифрация и запись в файл. Далее прогоняю чтение из файла - читаю блок данных, визуально сравниваю с тем что записали - все верно, пытаюсь расшифровать - выдает белиберду. При этом попробовал расшифровать сразу после шифрования - все работает. При этом исходные данные одни и те же! Что за чудеса?
Код:
typedef unsigned char u8;
 
u8 n = 0;
u8 P[256];
u8 s = 0;
 
void setup(u8 * key, u8 * iv)
{
    long m, i;
    u8 temp;
    s = 0;
 
    for (i = 0; i != 256; i++)
    {
        P[i] = (u8)i;
    }
 
    for (m = 0; m != 768; m++)
    {
        s = P[(s + P[m & 0xff] + key[m % 64]) & 0xff];
        temp = P[m & 0xff];
        P[m & 0xff] = P[s & 0xff];
        P[s & 0xff] = temp;
    }
    for (m = 0; m < 768; m++)
    {
        s = P[(s + P[m & 0xff] + iv[m % 64]) & 0xff];
        temp = P[m & 0xff];
        P[m & 0xff] = P[s & 0xff];
        P[s & 0xff] = temp;
    }
    n = 0;
}
 
void crypt(u8 * input, u8 * output, long len)
{
    long i;
    u8 z, temp;
    for (i = 0; i != len; i++)
    {
        s = P[(s + P[n & 0xff]) & 0xff];
        z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
        temp = P[n & 0xff];
        P[n & 0xff] = P[s & 0xff];
        P[s & 0xff] = temp;
        n = (u8)((n + 1) & 0xff);
        output[i] = (u8)(input[i] ^ z);
    }
}
 
 
void writeToFileCrypt(product* head_a, char* filename) {
    FILE* ptrFile = fopen(filename, "w+b");
    if (ptrFile != NULL) {
        product* tmp = head_a;
        u8 key[64];
        u8 iv[64];
        u8 buf[SIZE_NAME];
        u8 buf1[SIZE_TYPE];
        strcpy((char*)key,"123456789qwertyuiop");
        strcpy((char*)iv,"asdfghjkl");
        do {
            setup(key, iv);
            crypt((u8*)tmp->name, buf, strlen((char*)tmp->name)+1);
 
            if(fwrite(buf, 1, SIZE_NAME, ptrFile) == SIZE_NAME)
                printf("Записано 50 байт\n");;
            //setup(key, iv); - если здесь расшифровать то все работает
            //crypt(buf, buf, 50);
 
            setup(key, iv);
            crypt((u8*)tmp->type, buf1, strlen((char*)tmp->type));
 
            if(fwrite(buf1,1,SIZE_TYPE,ptrFile) == SIZE_TYPE) printf("Записано 30 байт\n");;
 
            sprintf((char*)buf,"%i\0", tmp->count);
            setup(key, iv);
            crypt(buf, buf, strlen((char*)buf));
            if(fwrite(buf, 1, 5, ptrFile) == 5) printf("Записано 5 байт\n");
 
            sprintf((char*)buf, "%10.2f\0", tmp->price);
            setup(key, iv);
            crypt(buf, buf, strlen((char*)buf));
            if(fwrite(buf, 1, 20, ptrFile) == 20) printf("Записано 20 байт\n");;
 
            sprintf((char*)buf, "%i\0", tmp->isinshop);
            setup(key, iv);
            crypt(buf, buf, 1);
            fwrite(buf,1,1,ptrFile);
 
            tmp = tmp->next;
        } while (tmp != head_a);
        fclose(ptrFile);
    }
}
 
void readFromFileCrypt(product* head_a, char* filename){
    FILE* ptrFile = fopen(filename, "r+b");
    if (ptrFile != NULL) {
        product* tmp = head_a;
        u8 key[64];
        u8 iv[64];
        u8 buf[SIZE_NAME];
        u8 name[SIZE_NAME];
        u8 type[SIZE_TYPE];
        u8 count_tmp[50];
        u8 price_tmp[50];
        char isinshop_tmp;
        strcpy((char*)key, "123456789qwertyuiop");
        strcpy((char*)iv, "asdfghjkl");
        while (!feof(ptrFile)) {
 
            fread(buf,1,SIZE_NAME,ptrFile);
            setup(key, iv);
            crypt(buf, name, SIZE_NAME);
 
            fread(buf,1,SIZE_TYPE,ptrFile);
            setup(key, iv);
            crypt(buf, type, SIZE_TYPE);
 
            fread(buf,1,5,ptrFile);
            setup(key, iv);
            crypt(buf, count_tmp, 5);
 
            fread(buf,1,20,ptrFile);
            setup(key, iv);
            crypt(buf, price_tmp, 20);
 
            fread(buf,1,1,ptrFile);
            setup(key, iv);
            crypt(buf, buf, 1);
 
            if(head == NULL)
                head = addElem(head,(char*)name, (char*)type, atoi((char*)count_tmp), atof((char*)price_tmp), isinshop_tmp);
            else
                addElem(head, (char*)name, (char*)type, atoi((char*)count_tmp), atof((char*)price_tmp), isinshop_tmp);
        }
    }
}
Такое впечатление что при расшифровании для отображения выбирается не та кодировка.
Anton_Jag вне форума Ответить с цитированием
Старый 23.05.2018, 20:10   #2
Anton_Jag
Пользователь
 
Регистрация: 05.11.2009
Сообщений: 41
По умолчанию

Я делаю в codeblocks. Запустил этот код в visual studio 2017 - все работает! выходит проблема в настройках codeblocks.
Anton_Jag вне форума Ответить с цитированием
Старый 24.05.2018, 03:56   #3
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Черт его знает, тут у вас "дозапись",
Цитата:
FILE* ptrFile = fopen(filename, "w+b");
т.е. старое значение в файле никуда не делось. И от первых неудачных запусков продолжает вам выдавать. Уберите + (и для чтения тоже уберите). А в визуалке просто изменился путь к файлу и оно создало новый, который уже верный.
alexzk вне форума Ответить с цитированием
Старый 24.05.2018, 11:25   #4
Anton_Jag
Пользователь
 
Регистрация: 05.11.2009
Сообщений: 41
По умолчанию

убрал + осталось
Код:
FILE* ptrFile = fopen(filename, "wb");
При чтении тоже убрал
Код:
FILE* ptrFile = fopen(filename, "rb");
Удалили сам созданный ранее файл, чтобы создался новый.
Отследил какое выражение buf показывает дебагер для запиисываемого в файл
Код:
fwrite(buf, 1, SIZE_NAME, ptrFile);
в функции шифрования и записи
Далее пошагово пытаюсь расшифровать
Смотрю через дебагер что считалось в buf функцией
Код:
fread(buf,1,SIZE_NAME,ptrFile);
Считалось ровно то что записалось. buf при записи и при чтении идентичны.
Далее расшифровка
Код:
crypt(buf, name, SIZE_NAME);
и на выходе в name белиберда. При этом если запустить расшифровку crypt() в функции записи в файл то все получается верно. Как уже писал выше этот код не работает именно в codeblocks, запустил его в visual studio 2017 и прошелся пошагово - все работает. Проблема в том, что по заданию мне нужно использовать именно codeblocks.
Anton_Jag вне форума Ответить с цитированием
Старый 24.05.2018, 12:10   #5
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

1. замените все подобные
Цитата:
i != len;
на
Цитата:
i < len;
2. проверьте, хватает ли вам места для последего 0 в буферах...т.к. "строки" должны окончится 0. Т.е. буфер на 1 длиннее нужен. А вот strlen последний 0 не учитывает в суммарной длине. Мне кажется что-то тут гуляет, т.к. вы используете strlen для подсчета. Т.е. грубо говоря, если вы 0 не кодировали и не писали в файл, то после раскодировки и не прочтете, т.о. у вас строка в памяти не будет окончена 0 и вывод на экран, скажем, понапечатает вам мусора.

Точнее хз...код тут не весь, не ясно, как именно "не работает".

Хотя писать в файл 0 плохая идея, т.к. можно заметить, что шифрованое сообщение на 1 байт длинее, предположить, что это 0 и от обратного получить ключ. Лучше при чтении делать буфер +1 байт и последний байт присваивать 0, а еще лучше обнулить весь буфер memset(buf, 0, sizeof(buf));

Последний раз редактировалось alexzk; 24.05.2018 в 12:20.
alexzk вне форума Ответить с цитированием
Старый 24.05.2018, 12:38   #6
Anton_Jag
Пользователь
 
Регистрация: 05.11.2009
Сообщений: 41
Подмигивание

С нулями в конце строк проблем нет. Вот изменил теперь шифрую весь буфер. SIZE_NAME = 50;SIZE_TYPE=30;
Даже если бы символ конца не шифровало то то что до него должно быть нормально обработано.
Вот код полностью
Код:
typedef unsigned char u8;

u8 n = 0;
u8 P[256];
u8 s = 0;

void setup(u8 * key, u8 * iv)
{
	long m, i;
	u8 temp;
	s = 0;

	for (i = 0; i < 256; i++)
	{
		P[i] = (u8)i;
	}

	for (m = 0; m < 768; m++)
	{
		s = P[(s + P[m & 0xff] + key[m % 64]) & 0xff];
		temp = P[m & 0xff];
		P[m & 0xff] = P[s & 0xff];
		P[s & 0xff] = temp;
	}
	for (m = 0; m < 768; m++)
	{
		s = P[(s + P[m & 0xff] + iv[m % 64]) & 0xff];
		temp = P[m & 0xff];
		P[m & 0xff] = P[s & 0xff];
		P[s & 0xff] = temp;
	}
	n = 0;
}

void crypt(u8 * input, u8 * output, long len)
{
	long i;
	u8 z, temp;
	for (i = 0; i < len; i++)
	{
		s = P[(s + P[n & 0xff]) & 0xff];
		z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
		temp = P[n & 0xff];
		P[n & 0xff] = P[s & 0xff];
		P[s & 0xff] = temp;
		n = (u8)((n + 1) & 0xff);
		output[i] = (u8)(input[i] ^ z);
	}
}


void writeToFileCrypt(product* head_a, char* filename) {
	FILE* ptrFile = fopen(filename, "wb");
	if (ptrFile != NULL) {

		product* tmp = head_a;
		u8 key[64];
		u8 iv[64];
		u8 buf[SIZE_NAME];
		u8 buf1[SIZE_TYPE];
		u8 name[SIZE_NAME];
		strcpy((char*)key,"123456789qwertyuiop");
		strcpy((char*)iv,"asdfghjkl");
		do {
			setup(key, iv);
			crypt((u8*)tmp->name, buf, SIZE_NAME);
            fwrite(buf, 1, SIZE_NAME, ptrFile);

			setup(key, iv);
			crypt((u8*)tmp->type, buf1, SIZE_TYPE);
			fwrite(buf1,1,SIZE_TYPE,ptrFile);

			sprintf((char*)buf,"%i\0", tmp->count);
			setup(key, iv);
			crypt(buf, buf, 6);// макс длина int плюс для символа конца строки
			fwrite(buf, 1, 6, ptrFile);

			sprintf((char*)buf, "%10.2f\0", tmp->price);
			setup(key, iv);
			crypt(buf, buf, 11);
			fwrite(buf, 1, 11, ptrFile);

			sprintf((char*)buf, "%i\0", tmp->isinshop);
			setup(key, iv);
			crypt(buf, buf, 1);
			fwrite(buf,1,1,ptrFile);

			tmp = tmp->next;
		} while (tmp != head_a);
		fclose(ptrFile);
	}
}

void readFromFileCrypt(product* head_a, char* filename){
	FILE* ptrFile = fopen(filename, "rb");
	if (ptrFile != NULL) {
		product* tmp = head_a;
		u8 key[64];
		u8 iv[64];
		u8 buf[SIZE_NAME];
		u8 name[SIZE_NAME];
		u8 type[SIZE_TYPE];
		u8 count_tmp[50];
		u8 price_tmp[50];
		char isinshop_tmp;
		strcpy((char*)key,"123456789qwertyuiop");
		strcpy((char*)iv,"asdfghjkl");
		while (!feof(ptrFile)) {

			fread(buf,1,SIZE_NAME,ptrFile);
			setup(key, iv);
			crypt(buf, name, SIZE_NAME);

			fread(buf,1,SIZE_TYPE,ptrFile);
            setup(key, iv);
			crypt(buf, type, SIZE_TYPE);

			fread(buf,1,6,ptrFile);
			setup(key, iv);
			crypt(buf, count_tmp, 5);

			fread(buf,1,11,ptrFile);
			setup(key, iv);
			crypt(buf, price_tmp, 20);

			fread(buf,1,1,ptrFile);
			setup(key, iv);
			crypt(buf, buf, 1);

			if(head == NULL)
				head = addElem(head,(char*)name, (char*)type, atoi((char*)count_tmp), atof((char*)price_tmp), isinshop_tmp);
			else
				addElem(head, (char*)name, (char*)type, atoi((char*)count_tmp), atof((char*)price_tmp), isinshop_tmp);
		}
	}
}

int main()
{
    SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	char name_tmp[100];
	char type_tmp[50];
	int count_tmp;
	float price_tmp;
	char isinshop_tmp;
	int pos;
	int posfield;
	char filename[30];
    char test[50];

	inputElem(name_tmp, type_tmp, &count_tmp, &price_tmp, &isinshop_tmp);
	head = addElem(head,name_tmp, type_tmp, count_tmp, isinshop_tmp, price_tmp);
	
	writeToFileCrypt(head, "outcrypt.txt");
	readFromFileCrypt(head, "outcrypt.txt");
return 0;
}
Anton_Jag вне форума Ответить с цитированием
Старый 24.05.2018, 12:44   #7
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

В функции чтения забыли

Цитата:
fclose(ptrFile);
но пока это не оно, т.к. последний вызов - ОС сама чистит.

Цитата:
u8 key[64];
u8 iv[64];

strcpy((char*)key,"123456789qwertyu iop");
strcpy((char*)iv,"asdfghjkl");
Здесь у вас 64 байта ключа, забиты мусором (в обоих случаях) - СЛУЧАЙНЫМ. Вы в них помещаете довольно короткую строку. А доступ идет ко всем 64 байтам

Цитата:
key[m % 64]
Т.о. у вас буквально случайные ключи при каждом запуске чтения и записи. Для чтения 1 случ., для записи 2й случ. В тестовой сборке визуалка туда сует или 0 или 0хСС, вот потому и работает.
Хочу отметить, этот код сплошной пример "как не нужно делать", надеюсь, это не в онлайн магазин пойдет?

Последний раз редактировалось alexzk; 24.05.2018 в 12:58.
alexzk вне форума Ответить с цитированием
Старый 24.05.2018, 12:58   #8
Anton_Jag
Пользователь
 
Регистрация: 05.11.2009
Сообщений: 41
По умолчанию

Вот архив проекта на CodeBlock полностью
Вложения
Тип файла: rar DBShop.rar (43.3 Кб, 7 просмотров)
Anton_Jag вне форума Ответить с цитированием
Старый 24.05.2018, 12:59   #9
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от Anton_Jag Посмотреть сообщение
Вот архив проекта на CodeBlock полностью
Обновите страницу - пост выше я добавил про случайные ключи.
alexzk вне форума Ответить с цитированием
Старый 24.05.2018, 13:00   #10
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Выставьте кодировку UTF-8, на линукс русский там не читаем ))
alexzk вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шифрование VMPC Namide C++ Builder 0 14.05.2012 17:08
Шифрование Dexman23 Помощь студентам 0 20.03.2012 20:54
Шифрование cheef Общие вопросы Delphi 2 26.06.2010 10:35
Шифрование SnowSin Помощь студентам 0 13.12.2009 12:14
Алгоритм VMPC Satgoblin Помощь студентам 6 05.07.2009 20:27