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

Man

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

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

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

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

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

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

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

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

Code:
cat in_file.txt | ./enc2_io e generated.key > out_file.enc

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

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

Code:
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;

}
 
Top