Чтение файла, шифрование Blowfish - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Помогите пожалуйста, очень срочно. Моя задача реализовать алгоритм шифрования 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 пропустил для экономии места
    0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
    0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
    0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6}
    };
 
//Ключи шифрования
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;
}
 
//Функция F(x)
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];         //17-й
    *high ^= ctx->P[17];        //и 18-й ключ XOR-ся с выходными блоками последнего раунда
}
 
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

Решение задачи: «Чтение файла, шифрование Blowfish»

textual
Листинг программы
blowfish_decrypt_block(ctx, &high, &low);//расшифровываю
fprintf(f2, "%08x%08x", high, low);     //записываю в файл

Объяснение кода листинга программы

  1. blowfish_decrypt_block(ctx, &high, &low); - выполняется операция расшифровки блоков данных с использованием алгоритма Blowfish.
  2. fprintf(f2,%08x%08x, high, low); - выполняется запись в файл значения двух переменных, которые были получены после расшифровки.

ИИ поможет Вам:


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

Оцени полезность:

9   голосов , оценка 4 из 5