• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Почти идеальное шифрование

XSSBot

Форумный бот
Пользователь
Регистрация
31.12.2005
Сообщения
1 473
Реакции
898
Автор sergest
Статья написана для
Конкурса статей #10


Если почитать книгу Шнаейра по криптографии, то можно наткнуться на абзац о том, что невзламываемое шифрование существует.
Этот алгоритм называется "Одноразовый блокнот".
Берется случайная последовательность байтов, которая будет называться ключом, по длине равная шифруемому сообщению и,
допустим, проводится операция XOR с байтами сообщения.
В итоге получаем зашифрованное сообщение которое невозможно взломать даже через тысячи лет,
даже "квантовыми компьютерами", которые на самом деле ничего не делают кроме выдачи случайных битов.
Не могу их не упомянуть потому что программы раздувают кодом с "защитой от постквантового апокалипсиса", которого не будет,
как и не существует термоядерных реакторов, реализацю которых откладывают каждые 20 лет на еще 20 лет.
Просто существуют области, в которых можно вечно зарабатывать деньги на обещаниях.

Извините меня за отступления от темы, но они помогают охватить более обширную картину и задуматься более широко.
Чуть позже напишу к чему это.

Зашифрованное одноразовым блокнотом сообщение невозможно взломать именно потому что байты ключа случайные.
Но если очень хочется, то можно написать любой текст такой же длины, провести операцию XOR с зашифрованным сообщением,
якобы получить "тот самый ключ шифрования", и утверждать что это именно он и сообщение именно такое.
Что интересно что часть людей купится на такие утверждения.
Почему-то люди плохо понимают слово "профанация" и вместо обсуждения самой профанации обсуждают ее последствия.
Это я намекаю на электронные голосования.
Даже, казалось бы профессионалы, употребляют "мы еще к ним не готовы" вместо "да вас обвели вокруг пальца".

Основной недостаток "Одноразового блокнота" в том что такой ключ трудно передать получателю сообщения - он слишком большой.

Но, как говорят, наш мир не идеальный, все в нем коряво и все не так.
Дак почему же и нам не сделать шаг назад и не попробовать "почти идеальное шифрование".
Вместо абсолютно случайной последовательности байтов ключа использовать псевдослучайную, но с длинным периодом повторения.
В интернете я нашел простой генератор псевдослучайной последовательности байтов - https://zxpress.ru/article.php?id=8675
Реализуется он десятком строк кода и написано что повторяемость его 4.6*10^18.


Программа называется enc2_io потому что это вторая версия, которая шифрует поток байтов - это более гибко, чем указывать файлы.
Указать нужно только файл ключа, который уже существует, если мы декодируем или который будет создан если кодируем.

Программу нужно запускать так:

* Для шифрования файла:

Код:
cat in_file.txt | ./enc2_io e generated.key > out_file.enc

Т.е. отправляем файл в стандартный вход enc2_io указав опцию "e" для шифрования и файл в который будет помещен созданный ключ.

* Для расшифровки файла:

Код:
cat out_file.enc | ./enc2_io d generated.key > out_file.txt

Ниже приводится сама программа. Как вы увидите размер ее очень маленький.
И у меня вопрос только к генератору псевдослучайной последовательности.
Статью я пишу в надежде что кто-то сможет оценить качество генератора.
А если нет, то можно хотя бы похоливарить о том, что нам подсовывают заранее взламываемые алгоритмы,
а вот можно в 140 строк зашифроваться как минимум до следующего тысячелетия.
Поэтому я и отклонялся от темы - в шифровании тоже достаточно много профанации.
В книжке Шнайера это и описано, что раньше применяли достаточно плохие алгоритмы.
И остается вопрос: а изменилось ли что-то принципиально?
Жизнь не так уж и сложна, многое из того что нам нужно валяется под носом,
но мы не можем этого увидеть и ведемся на маркетинговые уловки, покупая хлам который того не стоит.

Давайте, закидывайте меня камнями, будем думать...

C:
/*
    Compile in Linux:

        tcc -o enc2_io enc2_io.c

    Download for Windows:

        http://download.savannah.gnu.org/releases/tinycc/

    Compile in Windows:

        C:\enc2_io>\tcc\tcc.exe -o enc2_io.exe enc2_io.c
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>

#define BUF_SIZE 1048576

int main (int argc, char* argv[]) {

    unsigned char  enc[256];                         // random array
    unsigned char  *buf;                             // buffer for encode
    unsigned int   i,j,n;                            // counters for loop
    FILE           *fd_key;
    char           s[16] = "0123456789abcdef";
    unsigned char  e[512];

    // allocate memory buffer

    buf = malloc (BUF_SIZE);
    if ( buf == NULL ) {

        fprintf (stderr, "can't allocate memory for buffer\n");
        return -1;

    }



    if ( argc < 3 ) {

        fprintf (stderr, "please, say me direction and key file name\n");
        return -2;

    } else if ( argc == 3 ) {
        
        // try read key from file
 
        fd_key  = fopen (argv[2], "rb");
        if ( fd_key == NULL ) {

            // fill random array
    
            srand (time(NULL));
            for (i = 0; i < 256; i++)
            {
                enc[i] = rand();
                e[i*2+0] = s[ (enc[i] & 0xf0) >> 4 ];
                e[i*2+1] = s[ (enc[i] & 0x0f) >> 0 ];
                //printf("%02hhx", enc[i]);
            }
            //printf("\n");

            // create key file name

            fd_key = fopen (argv[2], "wb+");
            if ( fd_key == NULL ) {
                fprintf (stderr, "can't open for write '%s'\n", argv[2]);
                return -3;
            }

            // store key to file

            fwrite (e, 1, 512, fd_key);
            fclose (fd_key);

        } else {

            fread (e, 1, 512, fd_key);
            fclose (fd_key);

            // convert ascii key to binary data

            for (i = 0; i < 256; i++) {
                j = e[i*2+0] - 0x30;
                if (j>9) { j = (j & 0xdf) - 7; }
                n = e[i*2+1] - 0x30;
                if (n>9) { n = (n & 0xdf) - 7; }
                enc[i] = ((j << 4) | n);
                //printf("%02hhx", enc[i]);
            }
            //printf("\n");

        }

    } else {

        fprintf (stderr, "too many arguments\n");
        return -4;

    }



    // encode or decode

    j = 0;
#ifdef _WIN32
    /* win32 and win64 fix */
    setmode(fileno(stdin), O_BINARY);
    setmode(fileno(stdout), O_BINARY);
#endif
    if ( strcmp (argv[1], "e") ) {
        while (n = fread (buf, 1, BUF_SIZE, stdin)) {
            for (i = 0; i < n; i++) {
                buf[i] = (buf[i] + enc[j & 0xff]) & 0xff;
                enc[(j+55) & 0xff] = (enc[(j+1) & 0xff] + enc[(j+32) & 0xff]) & 0xff;
                j++;
            }
            fwrite (buf, 1, n, stdout);
        }
    } else {
        while (n = fread (buf, 1, BUF_SIZE, stdin)) {
            for (i = 0; i < n; i++) {
                buf[i] = (buf[i] - enc[j & 0xff]) & 0xff;
                enc[(j+55) & 0xff] = (enc[(j+1) & 0xff] + enc[(j+32) & 0xff]) & 0xff;
                j++;
            }
            fwrite (buf, 1, n, stdout);
        }
    }

    free  (buf);
    //fprintf (stderr, "%d bytes\n", j);

    return 0;

}
 
Последнее редактирование модератором:
Пожалуйста, обратите внимание, что пользователь заблокирован
Вся проблема в том, что это имеет смысл только в том случае, если этот самый блокнот является случайным. Но в мире компуктеров нет ничего случайного, только псевдослучайное. Практически любой потоковый шифр, типа RC4, это - по своей сути ксор с алгоритмом генерации псевдослучайных чисел с достаточно большим периодом. Допустим, ты с помощью srand проинициализировал ГПСЧ текущим временем, а потом с помощью rand создал свой замечательный блокнот. Проблема в том, что если кто-то знает, что ты использовал rand, то вместо размера ключа 256-бит в том же AES, ты имеешь ключ меньше 32-бит (rand - линейный конгруэнтный ГПСЧ по модуль 2 в 31). Если кто-то знает, что ты для его инициализации использовал текущее время, то ключей для перебора останется всего несколько десятков тысяч (а то и меньше, если вдруг у зашифрованного файла сохранилась метка времени его создания).
 
Вся проблема в том, что это имеет смысл только в том случае, если этот самый блокнот является случайным. Но в мире компуктеров нет ничего случайного, только псевдослучайное. Практически любой потоковый шифр, типа RC4, это - по своей сути ксор с алгоритмом генерации псевдослучайных чисел с достаточно большим периодом. Допустим, ты с помощью srand проинициализировал ГПСЧ текущим временем, а потом с помощью rand создал свой замечательный блокнот. Проблема в том, что если кто-то знает, что ты использовал rand, то вместо размера ключа 256-бит в том же AES, ты имеешь ключ меньше 32-бит (rand - линейный конгруэнтный ГПСЧ по модуль 2 в 31). Если кто-то знает, что ты для его инициализации использовал текущее время, то ключей для перебора останется всего несколько десятков тысяч (а то и меньше, если вдруг у зашифрованного файла сохранилась метка времени его создания).
Я думаю, что мы можем очень близко подойти к случайности, если будем получать её из природы, потому что, например, в физике молекулы воздуха движутся случайным образом через пространство. Поэтому в будущем мы увидим более специализированное оборудование, чьей единственной целью будет генерация случайности с использованием физических явлений, которые уже существуют в природе. Например, TPM 2.0 использует тепловой шум или другие формы электронного шума для создания случайных чисел.
 
Я думаю, что мы можем очень близко подойти к случайности, если будем получать её из природы, потому что, например, в физике молекулы воздуха движутся случайным образом через пространство. Поэтому в будущем мы увидим более специализированное оборудование, чьей единственной целью будет генерация случайности с использованием физических явлений, которые уже существуют в природе. Например, TPM 2.0 использует тепловой шум или другие формы электронного шума для создания случайных чисел.
Если уже задушить то, если бы мы знали точное начальное положение, скорость и направление каждой молекулы, а также могли учитывать все силы, действующие на неё (гравитацию, взаимодействия с другими молекулами, электромагнитные поля и т.д.), то теоретически можно было бы точно предсказать её движение, то по сути это тоже псевдослучайность. Детерменизм. Просто на данном этапе развития, невозможно точно подсчитать какой либо порядок. Не считая принцип неопределенности
 
Последнее редактирование:
Статью я пишу в надежде что кто-то сможет оценить качество генератора.
Давайте, закидывайте меня камнями, будем думать...
Статья написана на отъебись. По ссылке ненужные куски ассемблерного кода и изобретение велосипеда - LFSR/xorshift, это примерно 1965-й год. В самой статье бредовый код на плохом си, где для "шифрования" щедро выделяется массив аж в 512 байт, а для генерации ключа изначально используется сишный rand(). Период это только самый первый шаг при оценке качества. Если генератор с длинным периодом, но он позволяет угадать следующее число, то это хорошее качество или как? :) Помнится, кто-то с помощью Z3 солвера так гугловский генератор угадал.
 
From my point of view, the main problem is that how to send one-time notepad from one user to another even if the key is absolutely random. If they live in the same country ok it works, but what if one of them should fly somewhere he can't just grab his one-time notepad, cuz custom's measures.
 
То что написал ТС - это совсем не "почти идеальное шифрование". А если говорить более прямо, то это не является шифрованием вообще.
Это что-то ближе скорее к обфускации последовательности байт.
А вообще даже забавно наблюдать, как регулярно появляются персонажи, которые прочитав статью про шифр Вернама тут же бегут писать свой вариант "идеального шифрования". Это напомниает какие-то регулярные и наивные попытки создать вечный двигатель, хотя в любом школьном учебнике по физике напсиано, что это невозможно.
Ребят, ну поймите вы что чудес не бывает. Нельзя так просто взять шифр Вернама и перенести его в область реального компутерного применения. Если бы это было возможно, то никто бы не тратил вообще время на разработку всех потоковых шифров, которые применяются сейчас на практике (RC4, salsa и тп). Все бы просто юзали этот "одноразовый блокнот" и не парились.
 
С появлением асимметричной криптографии этот тип шифра стал нужен только для частного использования. Существует множество типов шифров, но они не так практичны. Если вы используете его для обмена данными, вам нужно найти безопасный способ передачи ключа получателю!
 
Вся проблема в том, что это имеет смысл только в том случае, если этот самый блокнот является случайным. Но в мире компуктеров нет ничего случайного, только псевдослучайное. Практически любой потоковый шифр, типа RC4, это - по своей сути ксор с алгоритмом генерации псевдослучайных чисел с достаточно большим периодом. Допустим, ты с помощью srand проинициализировал ГПСЧ текущим временем, а потом с помощью rand создал свой замечательный блокнот. Проблема в том, что если кто-то знает, что ты использовал rand, то вместо размера ключа 256-бит в том же AES, ты имеешь ключ меньше 32-бит (rand - линейный конгруэнтный ГПСЧ по модуль 2 в 31). Если кто-то знает, что ты для его инициализации использовал текущее время, то ключей для перебора останется всего несколько десятков тысяч (а то и меньше, если вдруг у зашифрованного файла сохранилась метка времени его создания).
Это как бы базовый набросок. Да, тут два тонких места - надо не rand, а другую функцию, забыл какую из стандартной библиотеки даже, которую рекомендуют для криптографии, и второе место это вот сам псевдослучайный генератор. Я не математик... кто бы проанализировал бы его...
 
Статья написана на отъебись. По ссылке ненужные куски ассемблерного кода и изобретение велосипеда - LFSR/xorshift, это примерно 1965-й год. В самой статье бредовый код на плохом си, где для "шифрования" щедро выделяется массив аж в 512 байт, а для генерации ключа изначально используется сишный rand(). Период это только самый первый шаг при оценке качества. Если генератор с длинным периодом, но он позволяет угадать следующее число, то это хорошее качество или как? :) Помнится, кто-то с помощью Z3 солвера так гугловский генератор угадал.
Не 512, а аж 256. Следующее число не угадать потому что массив случайных чисел. Да, вместо rand() нужна другая функция, которая есть в стандартной библиотеке, забыл какая. Статья не на отъебись, а очень кратко возможно, но вроде же все понятно. Непонятно чем плох 1965 год. Принцип KISS придуман в 1960. Это попытка ему следовать. К сожалению в вашем сообщении только общее отношение к статье. Хотелось бы больше конкретики. 256 байт это по сути инициализация псевдослучайного генератора. Но вообще если нет претензий кроме "устаревшая модель велосипеда", то значит идея правильная, главное что он едет. А то что не модный - это второстепенно.
 
С появлением асимметричной криптографии этот тип шифра стал нужен только для частного использования. Существует множество типов шифров, но они не так практичны. Если вы используете его для обмена данными, вам нужно найти безопасный способ передачи ключа получателю!
Пишут что ассиметричные хуже, и используются только для инициализации обмена, а потом работают симметричные т.к. короче ключи и быстродейственней.
 
Все бы просто юзали этот "одноразовый блокнот" и не парились.
Это так не работает. Люди очень любят париться. Для того чтобы выкачивать деньги нужно постоянно что-то хорошее объявлять устаревшим. Запланированное устаревание не существовало бы. Поглядите книгу по ТРИЗ, там описано как много лишнего люди придумывают.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
тут два тонких места
Тут много тонких мест, которые уже давно решены в привычной всем криптографии. Во-первых, принцип Кергоффса: вся "криптостойкость" такой системы по сути лежит на том, что никто не должен знать алгоритм, по которому ты сгенерировал свой блокнот, в противном случае вне зависимости от криптостойкости алгоритма ГПСЧ размер "ключа" составит размер данных для инициализации ГПСЧ. Во-вторых, этот подход совершенно не масштабируемый по объему данных, как ты собираешься безопасно передавать ключ другому участнику, которому надо будет расшифровывать сообщения от тебя? Допустим в обычной криптографии для этого можно использовать асимметричное шифрование, типа протокола Диффи-Хеллмана, но тогда тебе надо обработать асимметричным алгоритмом по сути весь размер твоих данных.

Я не математик
Именно поэтому тебе не стоит изобретать свои алгоритмы шифрования: это, между прочим, первое правило криптографии. Не являясь специалистом в области, ты не сможешь сделать что-то более криптостойкое, чем существующие алгоритмы. Скорее всего ты допустишь несколько критических ошибок, из-за которых специалисты в области быстро вскроют твою криптосхему.

Есть причины, почему современная криптография такая, какая она есть, и есть много причин, почему такое, как ты говоришь: "почти идеальное" шифрование никто не использует. Если бы это было практично, то оно бы использовалось повсеместно, но вместо этого мы везде видим привычные алгоритмы.

Ну и да, я уже говорил, что ксор с алгоритмом ГПСЧ - это очень многие поточные шифры, проще взять один из них и не выдумывать себе проблем с выбором "криптостойкого" ГПСЧ.
 
Не 512, а аж 256. Следующее число не угадать потому что массив случайных чисел. Да, вместо rand() нужна другая функция, которая есть в стандартной библиотеке, забыл какая. Статья не на отъебись, а очень кратко возможно, но вроде же все понятно. Непонятно чем плох 1965 год. Принцип KISS придуман в 1960. Это попытка ему следовать. К сожалению в вашем сообщении только общее отношение к статье. Хотелось бы больше конкретики. 256 байт это по сути инициализация псевдослучайного генератора. Но вообще если нет претензий кроме "устаревшая модель велосипеда", то значит идея правильная, главное что он едет. А то что не модный - это второстепенно.
Аж 512, это длина файла "ключа". Который на самом деле потом даже не используется как ключ, а как не пойми что - как куча сидов, но длиной 8 бит. Объясняю ещё раз для непонятливых про 1965-й год - в статье описан давно известный классический алгоритм, но он подаётся как что-то новое, оригинальное. Конкретика также вполне мной изложена - аффтар явно в упор не понимает темы, по которой пытается написать статью. "Я не математик, я навалаил кода - давайте, разбирайтесь." Это так не работает. :)
 
Аж 512, это длина файла "ключа". Который на самом деле потом даже не используется как ключ, а как не пойми что - как куча сидов, но длиной 8 бит. Объясняю ещё раз для непонятливых про 1965-й год - в статье описан давно известный классический алгоритм, но он подаётся как что-то новое, оригинальное. Конкретика также вполне мной изложена - аффтар явно в упор не понимает темы, по которой пытается написать статью. "Я не математик, я навалаил кода - давайте, разбирайтесь." Это так не работает. :)
Как можно подавать алгоритм как что-то новое давая на него ссылку. Новизна и оригинальность тут в количестве строк кода и отсутствия зависимостей от сторонних библиотек. Вобщем-то и вопрос в качестве этого старого алгоритма. И вот что еще нашел: "In FreeBSD 13, rand() is implemented using the same 128-byte state LFSR generator algorithm as random(3).". Надо покопаться, возможно это оно и есть.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
tq.png
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх