XOR на очень большом файле - PullRequest
       15

XOR на очень большом файле

0 голосов
/ 01 ноября 2009

Я хотел бы XOR очень большой файл (~ 50 Go).

Точнее, я хотел бы сделать это, XOR каждый блок из 32 байтов открытого текста (из-за нехватки памяти) с ключом 3847611839 и создать (блок после блока) новый файл шифра.

Спасибо за любую помощь !!

Ответы [ 4 ]

3 голосов
/ 01 ноября 2009

Как отмечается в комментарии starblue, «имейте в виду, что это в лучшем случае запутывание, а не шифрование». И это, вероятно, даже не запутывание.

Одним из свойств XOR является то, что (Y xor 0) == Y. Что это означает для вашего алгоритма, так это то, что для любого места в вашем очень большом файле, где есть прогоны нулей (что, по всей видимости, с учетом размера файла), ваш ключ будет отображаться в файле шифра. Обычный день.

Еще одна приятная особенность зашифрованных данных XOR заключается в том, что если у кого-то есть и открытый текст, и зашифрованный текст, то XOR, объединяющий эти элементы вместе, дает вам выход, в котором ключ, используемый для выполнения шифра, повторяется снова и снова. Если человек знает, что эти 2 файла являются парой открытого текста / зашифрованного текста, он узнал ключ, который является плохим, если ключ используется для более чем одного шифрования. если злоумышленник не уверен, что открытый текст и зашифрованный текст связаны между собой, он получит довольно хорошую идею после этого, поскольку ключ является повторяющимся шаблоном в выходных данных. Ничто из этого не является проблемой с одним временным блоком, потому что каждый бит клавиши используется только один раз, поэтому один узнает что-то новое из этой атаки.

Многие люди допускают ошибку, полагая, что поскольку одноразовая клавиатура доказуемо неразрывна, шифрование XOR может быть в порядке, если оно выполнено правильно, поскольку основная операция выполняется одинаково. Разница в том, что один временный блок использует каждый случайный бит ключа ровно один раз. Таким образом, среди прочего, если в открытом тексте есть ряд нулей, о ключе ничего не известно, в отличие от простого шифра XOR с фиксированным ключом.

Как сказал Брюс Шнайер: «В этом мире существует два вида криптографии: криптография, которая не дает вашей младшей сестре читать ваши файлы, и криптография, которая не дает крупным правительствам читать ваши файлы».

Шифр ​​XOR едва ли является доказательством младшей сестры - если даже это.

3 голосов
/ 01 ноября 2009

Это звучало как веселье и не похоже на домашнее задание.

У меня нет ранее зашифрованного файла xor, чтобы попробовать, но если вы конвертируете один назад и вперед, разница не будет.

Это я попробовал по крайней мере. Наслаждайтесь! :) Это xor каждые 4 байта с 0xE55 переменнойBF, я полагаю, это то, что вы хотели.

Вот bloxor.c

// bloxor.c - by Peter Boström 2009, public domain, use as you see fit. :)

#include <stdio.h>

unsigned int xormask = 0xE555E5BF; //3847611839 in hex.

int main(int argc, char *argv[])
{
    printf("%x\n", xormask);
    if(argc < 3)
    {
        printf("usage: bloxor 'file' 'outfile'\n");
        return -1;
    }

    FILE *in = fopen(argv[1], "rb");
    if(in == NULL)
    {
        printf("Cannot open: %s", argv[2]);
        return -1;
    }

    FILE *out = fopen(argv[2], "wb");

    if(out == NULL)
    {
        fclose(in);
        printf("unable to open '%s' for writing.",argv[2]);
        return -1;
    }
    char buffer[1024]; //presuming 1024 is a good block size, I dunno...

    int count;

    while(count = fread(buffer, 1, 1024, in))
    {
        int i;
        int end = count/4;
        if(count % 4)
            ++end;

        for(i = 0;i < end; ++i)
        {
            ((unsigned int *)buffer)[i] ^= xormask;
        }
        if(fwrite(buffer, 1, count, out) != count)
        {
            fclose(in);
            fclose(out);

            printf("cannot write, disk full?\n");

            return -1;
        }
    }

    fclose(in);
    fclose(out);

    return 0;
}
1 голос
/ 01 ноября 2009

Если ваш вопрос заключается в том, как сделать это, не используя дополнительное место на диске, я просто прочитал бы фрагменты, кратные 32 байтам (как можно больше), поработал бы с блоком в памяти, а затем записал снова. Вы должны быть в состоянии использовать функции ftell и fseek для этого (конечно, при условии, что тип long достаточно большой).

Это может быстрее отобразить файл в памяти, если вы сможете сэкономить столько из своего адресного пространства (и ваша ОС его поддерживает), но я сначала попробую самое простое решение.

Конечно, если пробел не является проблемой, просто прочитайте куски и запишите их в новый файл, что-то вроде следующего (псевдокод):

open infile
open outfile
while not end of infile:
    read chunk from file
    change chunk
    write chunk to outfile
close outfile
close infile

Этот тип чтения / обработки / записи - довольно простой материал. Если у вас есть более сложные требования, вы должны обновить свой вопрос с ними.

1 голос
/ 01 ноября 2009

Вам необходимо разработать решение на основе потоковой архитектуры: вы читаете входной файл в «потоке», изменяете его и записываете результат в выходной файл.

Таким образом, вам не нужно читать все файлы сразу.

...