С чего всё началось и зачем оно надо
Приветствую всех, кого заинтересовал заголовок моей первой статьи, которую я решил написать после защиты своей магистерской дипломной работы на тему шифрования и расшифровки данных с помощью хеш-функции xxHash. Хочу поделиться работой по созданию собственного алгоритма шифрования с достаточно интересной идеей (как мне кажется).
Актуальность темы шифрования и расшифровки данных с помощью хеш-функции обусловлена постоянным ростом объёмов информации и требований к её безопасности в современных компьютерных системах. В цифровую эпоху защита данных стала критически важной для обеспечения конфиденциальности, целостности и подлинности информации. Хеш-функции, как неотъемлемая часть многих криптографических алгоритмов, обеспечивают быстрое и эффективное преобразование больших объёмов данных в короткие хеш-значения, используемые для проверки целостности, создания цифровых подписей и аутентификации. Особенно актуальны хеш-функции в условиях быстрого развития технологий Интернета вещей (IoT), облачных вычислений, блокчейна и криптовалют. Рост количества кибератак и нарушений конфиденциальности данных также подчёркивает необходимость надёжных алгоритмов хеширования и шифрования для защиты информационных систем.
Базовая теория и немного Википедии
Шифрование — это процесс преобразования открытой информации (plaintext) в зашифрованную (ciphertext) с использованием алгоритма и ключа. Цель — защита данных от посторонних лиц без доступа к ключу.
Основные методы шифрования:
Симметричное — используется один ключ для шифрования и расшифровки. Примеры: AES, DES. Преимущество — высокая скорость, но есть риск утечки ключа.
Асимметричное — используется пара ключей: открытый (для шифрования) и закрытый (для расшифровки). Примеры: RSA, ECC. Обеспечивает большую безопасность, но работает медленней.
Расшифровка — обратный процесс, восстановление исходных данных с использованием нужного ключа и алгоритма. Без правильного ключа данные недоступны.
Шифрование и расшифровка обеспечивают:
Конфиденциальность — защита от несанкционированного доступа.
Целостность — данные не изменены при передаче или хранении.
Аутентичность — подтверждение личности отправителя/получателя.
Анонимность — скрытие личности и данных пользователя.
Свойства хеш-функций
Хеш-функция — алгоритм, преобразующий данные произвольной длины в хеш-значение фиксированной длины. Применяется для проверки целостности, аутентификации и хранения паролей.
Хеш-функции должны соответствовать ряду важных свойств, чтобы
обеспечить их эффективность и безопасность:
Детерминированность — одинаковый ввод → одинаковый хеш.
Фиксированная длина — независимо от объёма входа.
Быстрота вычислений — для работы с большими данными.
Устойчивость к коллизиям — трудно найти разные данные с одним хешем.
Односторонность — невозможно восстановить исходные данные по хешу.
Эффект лавины — малое изменение входа сильно меняет хеш.
Работа хеш-функции:
Получает данные (текст, файл, пароль и т. д.).
Обрабатывает их через математические операции.
Выдаёт фиксированное хеш-значение, представляющее входные данные.
Описания работы алгоритма
Наконец-то, после того как вы, скорее всего, успешно пролистали раздел с теорией и терминами, которые будут упоминаться дальше, пришло время поведать, как же всё-таки шифровать и расшифровывать данные с помощью хешей. Если бы задача стояла только в том, чтобы зашифровать данные, то проблем с этим нет, но мы же хотим потом и восстановить данные из хешей, а тут уже надо думать, как это можно сделать. На самом деле идея настолько простая, что я удивлён, что не встретил ничего внятного по этому поводу на просторах интернета. Для реализации алгоритма возьмём Python — лёгкий, понятный, с простым синтаксисом, который запал мне в душу. Понятное дело, что для универсальности алгоритма он должен работать с байтами — в финальном варианте так и есть, но для упрощения понимания возьмём пока что обычный текст, представленный в байтовом формате.
Основная идея
Основная идея шифрования базируется на нахождении такого хеша, который при соединении с частью открытого ключа и повторном хешировании даст новый хеш, который будет в определённом месте иметь часть открытых данных. В данном случае это будет начало хеша. Это значит, что нам сначала нужно сгенерировать случайный набор данных, длина которого будет равна длине сообщения, которое будет открытым ключом или шифротекстом и которое можно открыто передавать. Дальше мы должны найти список хешей, который будет закрытым ключом, в количестве, равном длине сообщения — на каждый символ текста свой хеш, который при расшифровке сообщения будет соединяться с определённой частью шифротекста. Каждый символ можно представить в байтовом виде — числом от 0 до 255, то есть 00–ff, если в hex-формате. Поэтому каждый символ (байт) шифруется двумя хешами — так наиболее быстро.
Выбор хеш-функции
Так как алгоритм использует хеширование, то нужно выбрать функцию, которая будет это делать. Желательно, чтобы она была быстрой. Среди прочих вариантов выбрал xxHash. Она очень быстрая, но не криптографическая, но нам это и неважно, так как сами хеши являются секретным ключом и не должны быть доступны посторонним. В любом случае можно выбрать другую, если нужно — это не так важно на данный момент.
Шифрование
Итак, перед нами текст, который нужно зашифровать, пусть это будет строка "Secret data". Для начала нужно сгенерировать случайную последовательность такой же длины, пусть это будет строка "Yuh6Gfhh8jC", причём в ней могут быть как числа, так и буквы верхнего и нижнего регистра. Дальше обе строки нужно представить в шестнадцатеричном формате (0xFF), дальше — hex, переводим и получаем следующее: "Secret data" → "5365637265742064617461", "Yuh6Gfhh8jC" → "5975683647666868386a43". Эту строку уже можно передавать — она является открытой частью шифрования. Дальше — самое интересное: нужно найти хеши. Для этого будем генерировать случайный набор из 8 байт, так как каждый байт в hex-формате представляется двумя символами, то на выходе получаем случайную hex-строку длиной 16 символов. Генерация строки для хеширования более 8 байт может привести к снижению производительности, с одной стороны, с другой — к повышению криптостойкости, так как у нас получается больший набор вариантов строк, которые можно использовать для генерации хешей, но пока для иллюстрации этого достаточно. Итак, берём первый символ из нашей строки шифротекста "5" и соединяем со случайно сгенерированными 8 байтами в hex-формате (пусть это будет следующая строка c135dc43589da553) — получается 5c135dc43589da553. Хешируем алгоритмом, выбранным ранее (xxHash), и получаем следующий хеш этой строки: 87a0552aa9ee4789. Видим, что на первом месте стоит 8, а нам нужно, чтобы было 5 (первый символ из 5365637265742064617461), поэтому продолжаем дальше генерировать байты и искать нужный хеш — по моим наблюдениям, в среднем для этого нужно около 10 попыток. Когда мы нашли нужный хеш, в нашем случае это будет daa41b6a5a06a744. Дальше возьмём следующий символ из строки 5975683647666868386a43 — это 9, нужный хеш 6d6adcbc4d769946 и так далее. На этом этапе мы зашифровали первую букву из нашего секретного сообщения Secret data, поскольку, напоминаю, что мы переводили байтовую строку в hex, а символ S в таком формате будет выглядеть как 53. Дальше по аналогии делаем это со всеми остальными символами. На выходе получим такой список хешей (секретный ключ).

Эту часть нужно держать в секрете — публичный ключ: Yuh6Gfhh8jC. Готово! Мы зашифровали сообщение "Secret data".
Расшифрование
Эта часть будет уже проще. Всё, что нам нужно сделать — это поочерёдно брать символы открытого ключа, соединять с соответствующим хешем из закрытого ключа, повторно хешировать и получить зашифрованное сообщение. Приступим. Первый символ открытого ключа — Y, но помним, что он кодируется в hex, поэтому будет 59. Нам нужна 5, первый хеш — daa41b6a5a06a744. Получаем входную строку для хеша: daa41b6a5a06a7445 (добавляем 5 в конец), хешируем и получаем вот такой выходной хеш: 5c5fb79952915a32. Видим, что на первом месте стоит символ 5 — хорошо! Давайте сделаем то же с 9 и хешем 6d6adcbc4d769946: добавляем 9 в конец — 6d6adcbc4d7699469 и также хешируем. Получаем: 3f8f00ac6fb63a2b, первый символ — 3. Итак, у нас есть строка "53", или символ S, если перевести её из байтового представления — это то, что мы и хотели получить: первая буква нашего зашифрованного сообщения Secret data! Поздравляю, всё получилось! Остальную работу пусть проделает уже бездушная машина.
Тестирование
А что по скорости?
Что ж, наверняка вас интересует скорость работы такого метода. Что ж, давайте проверим. Ссылку на код оставлю внизу, но для начала давайте немного улучшим код. Во-первых, сделаем хеш-таблицу и сжатие данных. Первое нужно для кеширования ранее найденных результатов, сохранения их и повторного использования. Второе — это сжатие данных: сжимать данные нужно, чтобы уменьшить длину сообщения и, соответственно, не только сократить время выполнения шифрования, но и уменьшить размер ключей. Чем короче сообщение — тем меньше нужно будет хешей. Для сжатия возьмём также быстрый алгоритм LZ4 и библиотеку для Python — py-lz4framed. RSA нам не конкурент, поэтому сразу возьмём быструю симметричную классику в виде AES и DES. Шифровать будем случайные байты, сгенерированные с помощью модуля os и функции urandom, размером 1 КБ, 100 КБ, 1 МБ, 20 МБ, 100 МБ. Запускаю я это всё на своём домашнем компьютере на Windows 10 с процессором Intel Core i7-11700F. Тестирование будет проходить со сжатием и без — для моего алгоритма — и с выводом следующей информации: название алгоритма и режим (только для моего), общее время в секундах, скорость обработки данных в МБ/сек и размер данных тоже в МБ.










И что мы видим? AES и DES значительно быстрее — оно и не удивительно. Средняя скорость моего алгоритма — 4.5 МБ/с, что при сжатии, что без него. Но это и понятно, поскольку данные не сжимаются. Также обратите внимание, что на выходе получается всегда в два раза больший файл — как уже говорил, это связано с тем, что каждый байт шифруется двумя хешами. Но ещё есть шанс на данных, которые хорошо сжимаются. Кто-то может посчитать, что это нечестно, так как для AES и DES сжатие не применяется. Возможно, в какой-то мере это и так, но всё же у них нет встроенного сжатия, а у моего алгоритма оно есть — и это плюс. Теперь возьмём строку, например, "Hello World" и повторим её миллион раз — посмотрим, какие будут результаты теперь.


Другое дело — добились при определённых данных скорости шифрования в 800 МБ/с, или 6.4 Гбит/с (для крутости звучания), и обогнали как AES, так и DES. На другие строчки не смотрим — они в рекламные заголовки всё равно не попадут. Так что да, именно так и работает маркетинг и реклама. А если серьёзно, то видно, что можно шифровать этим алгоритмом данные, которые хорошо сжимаются, или использовать его там, где скорость не критична.
Это вообще безопасно?
Да, и на это есть две причины. Первая — это то, что хеши являются закрытым ключом. Открытая часть — это, по сути, случайный набор байт, никак не связанный с шифруемыми данными. Вторая — это очень низкая вероятность подбора при условии, что сообщение достаточно длинное (хотя бы 100 байт). Поскольку взломать хеш невозможно, остаётся только подбор, но даже при этом непонятно, какой именно из полученных ответов правильный. Из потенциальных уязвимостей можно выделить то, что злоумышленнику видна длина сообщения. Но это также можно частично решить, генерируя в публичном ключе дополнительную последовательность случайной длины — что, кстати, уже реализовано.
Какие есть минусы?
Конечно, как и у любого алгоритма, не обходится без минусов. Первый — это очень большой размер ключей, особенно секретного: он по размеру минимум равен длине шифруемого сообщения, что может создавать неудобства. Второй — это не слишком высокая скорость: для скоростного шифрования трафика алгоритм не подойдёт, хоть он и хорошо параллелится. Также интересный факт — основное время тратится не на поиск хешей, а на прохождение по данным и создание секретного ключа.
Перспективы
Если немного доработать алгоритм так, чтобы открытым ключом были хеши, он станет более универсальным — но не только это. Что действительно важно — так это то, что поиск хешей, как минимум теоретически, можно перенести на GPU. Как показал майнинг, это может быть очень эффективно. Если кто-то сумеет реализовать это, то скорости шифрования могут многократно возрасти — и, думаю, без проблем обгонят AES и DES.
Заключение
Итак, идея алгоритма показана и рассказана, протестировали скорость, сделали выводы (каждый для себя) — и на этом можно расходиться.
Комментарии (37)
musk
13.07.2025 11:21Бессмысленно, см "шифр Вернама", если размер ключа равен размеру текста, но идея интересная.
fedorro
13.07.2025 11:21Ничего интересного, идея в корне провальная: помимо того что при шифровании на каждый символ сообщения нужно брутфорсить 8! байт того что тут называется "закрытым ключом", чтобы расшифровать шифротекст нужен и открытый и "закрытый ключ", которые при передаче перехватывают, и вообще без проблем расшифровывают текст.
musk
13.07.2025 11:21Точно, необходимость передачи закрытого ключа как-то упустил из виду.
Aarrtteemm Автор
13.07.2025 11:21Передача ключей это совсем другая тема
fedorro
13.07.2025 11:21Так Вы ни в теме шифрования, ни в теме ключей не разбираетесь.
Должно быть так: получаем пару открытый-закрытый ключ, передаем открытый ключ, которым можно зашифровать секрет и получить шифротекст, отправить владельцу закрытого ключа шифротекст - он сможет им расшифровать шифротекст, закрытый ключ не передается.
А у Вас - из открытого ключа и секрета получается не понятно что, что Вы называете "закрытый ключ". Отправляете получателю открытый ключ, а потом вдогонку ещё и закрытый, потому что из него секрет достается - в итоге нужно потратить кучу вычислительных ресурсов и передать в восемь раз больше данных, чтобы передать, фактически, незашифрованный текст (ибо если всё что надо передатьперехватят - всё расшифровано).
Aarrtteemm Автор
13.07.2025 11:21Я разбираюсь, обмен ключей идёт через разные каналы связи, или через один, но зашифрованный, или сам ключ должен быть зашифрованный, как это делается в паре RSA/AES, так же я написал что можно передавать хеши как открытый шифротекст, а сгенерированный байты как закрытый, можно и так и так
fedorro
13.07.2025 11:21Нет, не разбираетесь: если есть разные каналы, то их могут оба прослушивать, и надежность зависит не от вашего шифрования а от вероятности что не оба канала прослушивают. А если канал зашифрованый - то зачем ещё шифровать? AES - это шифрование с паролем, и там те-же проблемы, и для решения этих проблем придумали инфраструктуру открытых ключей, где можно всё передавать по открытым каналам, и даже если все передачи перехватят - не смогут расшифровать сообщение.
sic
13.07.2025 11:21Не понял примерно ничего. Вот тот самый список хешей (который Вы назвали секретным ключом), который размером с 32 х количество_символов_сообщения надо передавать, чтобы расшифровать шифртекст? Тогда у схемы относительно XOR только недостатки.
winwood
13.07.2025 11:21Ничего не понял. А если привлечь Алису и Боба? У Алисы есть открытый текст Secret data, Алиса "придумывает" шифртекст Yuh6Gfhh8jC. Далее Алиса используя открытый текст и шифртекст формирует секретный ключ их хэшей. И передает шифртекст Бобу. Вопрос - где Боб возьмет секретный ключ? Ведь заранее его передать нельзя. Он хронологически появляется после шифртекста.
Aarrtteemm Автор
13.07.2025 11:21Если немного доработать алгоритм так, чтобы открытым ключом были хеши, он станет более универсальным — но это не главное. Что действительно важно — так это то, что поиск хешей, как минимум теоретически, можно перенести на GPU.
В конце указал на это
dyadyaSerezha
13.07.2025 11:21Рост количества кибератак и нарушений конфиденциальности данных также подчёркивает необходимость надёжных алгоритмов хеширования и шифрования для защиты информационных систем.
Неверно. Подчёркивает, только если этот рост обусловлен растущим количеством прямых взломов зашифрованной инфы, а не поиском дырок в защите, человеческим фактором и прочее. Иначе получается решение проблемы, высосанной из пальца.
Ну и про длину ключа уже написали выше.
avost
13.07.2025 11:21магистерской дипломной работы на тему шифрования и расшифровки данных с помощью хеш-функции xxHash
Неужели никто из дипломной комиссии не задал вопроса - ну, хорошо, мы открыто передали шифротекст, а как теперь скрытно передать последовательность хешей - ключ, длиной больше шифротекста?
Причём, в отличии от простого одноразового блокнота, где можно заранее обменяться ключами при личной встрече, в данном случае ключевая информация появляется только после процедуры шифрования? И если такой канал существует, то почему по нему не передать само сообщение без этой бессмысленной возни?
В каком, говорите, вузе защищались? Магистерская, говорите, степень?
randomsimplenumber
13.07.2025 11:21Для магистерской работы как-то слабовато. Думаю, если бы Ривест с Шамиром так описали бы свой алгоритм - их бы до защиты не допустили
Aarrtteemm Автор
13.07.2025 11:21Если немного доработать алгоритм так, чтобы открытым ключом были хеши, он станет более универсальным — но это не главное. Что действительно важно — так это то, что поиск хешей, как минимум теоретически, можно перенести на GPU.
В конце указал на это
avost
13.07.2025 11:21Что действительно важно — так это то, что поиск хешей, как минимум теоретически, можно перенести на GPU.
Это как раз не важно. Но хуже всего то, что вы даже не понимаете проблемы... :(
доработать алгоритм так, чтобы открытым ключом были хеши
... и взламывать его можно будет даже не на gpu, а на калькуляторе.
Aarrtteemm Автор
13.07.2025 11:21Можно ваш калькулятор который может перебрать 256^n, где n длина сообщения?
Sap_ru
13.07.2025 11:21Во-первых, это потому, что у вас данных на выходе стало больше чем на входе. Супер эффективный шифр!
Во-вторых, что мешает зная первые несколько символов расшифровать сообщения, сделать перебор только для них и восстановить ваш "секретный" ключ?
В-третьих, ваш шифр ничего не решает, так вместо исходного текста вам в результате нужно каким-то безопасным образом передать больше/столько же информации, как и изначальный текст. А если вы идете это сделать, то зачем вам шифр?
Aarrtteemm Автор
13.07.2025 11:21А кто сказал что хеши одинаковые для одинаковых символов? Например символ "А" может кодироваться разными хешами
0CYBEaR0
13.07.2025 11:21Хеши без соли считаются на радужных таблицах при помощи тех же видеокарт. А как соль передавать? Как о "методе засолки" договариваться?
avost
13.07.2025 11:21Можно. Только сначала вы опубликуете вашу изменённую схему шифрования ( 'чтобы открытым ключом были хеши' ). А потом будем разбираться с калькулятором.
И не 256^n, а, как вам правильно написали ниже - 10 * n
Guestishe
13.07.2025 11:21Если бы вы сказали использовать майнер то да, но на GPU сейчас считают всё что угодно от графики до нейросетей и различных симуляций.
Sap_ru
13.07.2025 11:21Видим, что на первом месте стоит 8, а нам нужно, чтобы было 5 (первый символ из 5365637265742064617461), поэтому продолжаем дальше генерировать байты и искать нужный хеш — по моим наблюдениям, в среднем для этого нужно около 10 попыток
По ощущениям... Около 10 повторов...Господи, да тут ещё и хэш дерьмовый. Если у вас "около 10 попыток", то ваш хеш на раз ломается (можно найти функцию подбора исходного сообщения по хэшу). И если вы не можете ответить на вопрос "почему", то двойка вам вне зависимости от содержания остального текста (которых тоже бредовый)
Aarrtteemm Автор
13.07.2025 11:21Я вижу что вы абсолютно ничего не поняли, пожалуйста, ознакомьтесь внимательней с материалом или кодом
Sap_ru
13.07.2025 11:21Вы даже не понимаете, что именно не так в этой фразе :))) если написанное вами правда, то ваш шифр гарантированно ломается поиском коллизий. Но вы этого не поймёте, так как даже не знаете свойств хэш-функций. Сами свою статью читайте, может поймёте, в чём идиотизм. Вы же там вначале про свойства хэшей разглагольствуете, вот и читайте - вам читать полезно, а не писать.
А пока запомните: если у кого-то "по наблюдениям, в среднем нужно около 10 попыток", то где-то уже танцуют от радости специалисты по криптографии.
llllXl
13.07.2025 11:21Слишком много разного рода случайностей при работе алгоритма, что неприемлемо для шифрования. В статье только и написано "если то", "если это". Если работу рассматривать как практику для себя, чтобы понять как работают такие системы - нормально, но что-то серьёзное из этого вряд-ли получится, а давать майнерам вычислять хеши для шифрования твоего сообщения похоже на что-то из разряда "привет незнакомец, передай этот конверт тому молодому человеку за барной стойкой, старайся не вникать в процесс, а просто сделай это", не думаю что это надежено с точки зрения выполнимости, а вдруг сообщение не дойдёт, а вдруг свет отключат и считай потерял ты свое сообщение в блокчейне, а размножать блоки никто тебе не позволит
Aarrtteemm Автор
13.07.2025 11:21Я имел ввиду использовать GPU на локальном компьютере, где выполняется шифрования
0CYBEaR0
13.07.2025 11:21Просто как способ занять себя - отлично! В исследовании "отсутствие результата - тоже результат"
Как шифрование ради шифрования - ок, есть некоторый диапазон размеров данных, который можно ускорить, значительно потеряв в энергозатратах. Как часть науки о защите информации - бред, т.к. Ева может не только с линий связи снимать зашифрованный текст, а еще ковыряться в твоем ПК, засылать тебе троянов, оставлять бекдоры в ОС и аппаратуре, разработчиков которой она контролирует. И при всем при этом ты должен обеспечивать секретность закрытого ключа.
Перспективы
Если немного доработать алгоритм так, чтобы открытым ключом были хеши, он станет более универсальным — но это не главное. Что действительно важно — так это то, что поиск хешей, как минимум теоретически, можно перенести на GPU. Как показал майнинг, это может быть очень эффективно. Если кто-то сумеет реализовать это, то скорости шифрования могут многократно возрасти — и, думаю, без проблем обгонят AES и DES.
А зачем мне грузить GPU для отправки сообщения в мессенджере? Причем достаточно бездарно грузить. Когда я могу зашифровать его стойким симметричным ключом, а его - открытой частью 4/8/16/32к ключа на эллиптических кривых моего собеседника. И это быстро работает на CPU
А давайте теперь прикинем, что речь не о том, что мы мелкие какие-то операции будем на GPU загонять (прям сейчас представил лицо какого-нибудь дизайнера/проектировщика, у которого скорость рендера скачет из-за его активности на компе, потому что то и дело что-то шифруется. А лицо инженеров Nvidia представили, где в архитектуру профессиональных видеокарт закладывается высокая, но стабильная загрузка, а не как в игровых, которые стабильно высокую могут не пережить, но нормально справляются с пиковыми нагрузками) а замахнемся на какой-нибудь битлокер, который шифрует весь диск или VeraCrypt. Да фиг с ним с полнодисковым шифрованием. Представь себе efs шифрование на твоём алгоритме. Стандартным aes256 я быстро и надежно зашифрую какой-нибудь устав предприятия на 25 листов. А по твоей логике мне нужно будет сгенерировать еще один такой?
А теперь задумайся над тем, что еще есть куча требований по контролю за закрытым ключом, неизвлекаемости, надежной генерации (да, да шумовые диоды опупеют тебе выдавать последовательность такой длины, а если ты это будешь на видяхе делать, то любой нарушитель с физическим доступом все раскрутит). А неизвлекаемость, кстати, накладывает требования, кто бы мог подумать, к тому, что ключ не покидает контейнер, а, значит, твой бедный аппаратный токен будет шифровать все этом в не GPU. И как ты сделаешь извлекаемость в таком случае - не понятно.
vilgeforce
" очень большой размер ключей, особенно секретного: он по размеру минимум равен длине шифруемого сообщения " - с таким размером ключа достигается абсолютная стойкость шифрования и без плясок с хэшами ;-) Достаточно применить просто XOR
Aarrtteemm Автор
Достаточно применять существующие алгоритмы, тут просто идея и необычный подход к использованию хешей