Известная атака открытым текстом по алгоритму Берлекампа-Месси

Я реализовал алгоритм Berlekamp-Massey в ANSI C. У меня есть зашифрованный текст, который я хочу расшифровать, и первые 491 байт открытого текста.

Два файла

Я написал программу, которая использует Berlekamp-Massey как функцию, чтобы получить минимальный LFSR и найти следующие ключи, чтобы расшифровать остальную часть зашифрованного текста.

Я прочитал последние 4 байта открытого текста и XOR их с соответствующими 4 байтами в зашифрованном тексте, чтобы получить ключевой поток, который был использован. Затем я даю ключевой поток в качестве аргумента функции Берлекампа-Месси. Массив f содержит LFSR, рассчитанный Берлекампом-Мэсси в форме 0 и 1, которые представляют полином, описывающий LFSR.

Так что теперь я должен быть в состоянии рассчитать остаток ключевого потока как таковой: введите описание изображения здесь

Где pj представлен массивом f, si - поток ключей, а умножение - логическое AND. Я вычисляю следующие 32 бита потока ключей и XOR их с соответствующим зашифрованным текстом, чтобы получить открытый текст.

Как вы можете видеть, я сделал это только для первых 4 байтов, которые я хочу расшифровать, для целей тестирования.

Проблема в том, что созданный открытый текст неверен. Когда я открываю его с помощью gedit, я получаю это: введите описание изображения здесь

Несколько замечаний по поводу кода:

  1. bm () - это функция, реализующая алгоритм Берлекампа-Масси.
  2. int2bin () принимает десятичное число и заполняет массив соответствующим двоичным файлом.
  3. Я читаю текст, который я читаю, и ключ как целые числа, используя маскирование, умножение и деление с конкретными числами. Это проще, чем обрабатывать их в двоичном формате.

Код:

int main(int argc, char** argv) {
    short key_bin[32];  
    FILE plain_in, plain_out, *cipher_in;
    plain_in = fopen("plaintext_known.txt", "r");
    cipher_in = fopen("ciphertext_full.txt", "r");
    plain_out = fopen("plain_out.txt", "a");

    int plain32[4], cipher32[4], i, j, s, f[33], g[32], temp[33], n=0, d=0, count=1;
    unsigned long plain, cipher, keystream;

    fseek(plain_in, 488, SEEK_SET);
    plain32[3] = fgetc(plain_in);
    plain32[2] = fgetc(plain_in);
    plain32[1] = fgetc(plain_in);
    plain32[0] = fgetc(plain_in);
    printf("plain: %d %d %d %d\n", plain32[3], plain32[2], plain32[1], plain32[0]);

    fseek(cipher_in, 488, SEEK_SET);
    cipher32[3] = fgetc(cipher_in);
    cipher32[2] = fgetc(cipher_in);
    cipher32[1] = fgetc(cipher_in);
    cipher32[0] = fgetc(cipher_in);
    printf("cipher: %d %d %d %d\n", cipher32[3], cipher32[2], cipher32[1], cipher32[0]);

    plain = (unsigned long)plain32[3]*16777216 + (unsigned long)plain32[2]*65536 
            + (unsigned long)plain32[1]*256 + (unsigned long)plain32[0];
    cipher = (unsigned long)cipher32[3]*16777216 + (unsigned long)cipher32[2]*65536 
            + (unsigned long)cipher32[1]*256 + (unsigned long)cipher32[0];

    keystream = plain ^ cipher;
    int2bin(keystream, 32, key_bin);

    g[0]=1;
    f[0]=1;
    for(i=1; i<32; i++){
        f[i]=0;
        g[i]=0;
    }
    f[32]=0;

    bm(32, key_bin, f, g, temp, d, n, count);

    cipher32[3] = fgetc(cipher_in);
    cipher32[2] = fgetc(cipher_in);
    cipher32[1] = fgetc(cipher_in);
    cipher32[0] = fgetc(cipher_in);
    cipher = (unsigned long)cipher32[3]*16777216 + (unsigned long)cipher32[2]*65536 
            + (unsigned long)cipher32[1]*256 + (unsigned long)cipher32[0];

    keystream = 0;
    for(i=0; i<32; i++){

        s = f[1] & (int)key_bin[31];
        for(j=1; j<32; j++){
            s = s ^ (f[j+1] & (int)key_bin[31-j]);
        }

        if(s==1)
            keystream += (unsigned long)pow((double)2, (double)i);

    }

    plain = keystream ^ cipher;


    plain32[0] = plain & 255;
    plain32[1] = (plain & 65280)/256;
    plain32[2] = (plain & 16711680)/65536;
    plain32[3] = (plain & 4278190080)/16777216;

    fprintf(plain_out, "%c%c%c%c", plain32[3], plain32[2], plain32[1], plain32[0]);

    fclose(plain_in);
    fclose(plain_out);
    fclose(cipher_in);

    return (EXIT_SUCCESS);
}

0 ответов

Другие вопросы по тегам