По очевидным причинам не будем замахиваться на гигантов индустриальной криптографии вроде AES, а погрузимся, так сказать, в собственные криптографические изыскания с блекджеком и утехами.
Отчасти потому, что это интересно, отчасти потому, что моделируя что-то свое и сравнивая это с признанными стандартами, наглядно видишь контраст, эффективные решения и откровенные упущения, понимаешь, к чему можно стремиться для повышения эффективности.
Но довольно уже воды.
Допустим, наше веб-приложение написано на php, нуждается в обратимом шифровании и мы считаем, что в силах написать свою систему шифра.
Итак, напишем собственную систему обратимого шифрования с приватным и публичным ключом, такую, которая будет обладать следующими признаками мало мальски защищенного криптографического алгоритма:
- Наличие шумовых символов в итоговом шифре.
- Информация в каждом канале Отправитель-Адресат будет шифроваться по приватному ключу, причем функция соответствия будет уникальной для каждого ключа.
- Каждое сообщение будет получать дайджест-код — некий уникальный код, являющийся функцией от приватного ключа и исходного сообщения. Это требуется для того, чтобы добиться уникальности функции соответствия «исходный символ <=> закодированный символ» не только для канала «Отправитель-Адресат», но и для каждого отдельного сообщения.
Таким образом, даже если представить, что стало известно соответствие кодированных и исходных символов для конкретного сообщения посредством применения криптографического анализа, например, частотного анализа, то это не дает никаких преференций при исследовании другого сообщения. - Для усложнения частотного анализа будем кодировать каждый исходный символ сообщения двумя символами шифра.
Итак, что получилось.
Собственно говоря, итоговый результат посмотреть можно здесь
Класс SymCoder
Класс SymCoder включает в себя методы шифрования и дешифрования.
Шифрование осуществляет метод code(), принимающий на входе исходное сообщение.
Здесь сообщение по сгенерированной таблице соответствия в tab_coded создает зашифрованное сообщение, разбавленное по краям и внутри шумовыми символами.
Шумовые символы кстати уникальны для каждого канала отправитель-адресат, так как генерируются используя ключ канала, но не уникальны для сообщений. Используемые для шифрования символы в code_symbols представляют собой некоторые знаки пунктуации и символы вида %, @ и т.п.
На каждый кодируемый символ приходится два символа из code_symbols по понятным причинам, что их в несколько раз меньше, чем кодируемых символов.
Таблица соответствия create_tab_coded строится используя трансляцию хеша ключа сообщения в массив с количеством элементов, равным количеству элементов в массиве кодовых символов. Позиция начала обхода двухсимвольных кодов также всегда различна и связана с ключом канала. Это дает возможность быть уверенным, что алгоритм обхода кодируемых символов и соответствия им кодовых символов всегда (ну или гарантированно часто) будет различным.
К примеру, сообщение «привет, мир» будучи закодированным, выглядит вот так:
Digest-a00bf11d-&?==&!&?.@.@=!=-.?&1.#&?=:.:.1%!&-%@&@%~&1^#=?%%.!%+.?.~=?..&?%&&:%~.#%@&1&1.#=?.#.?.!&1==&=.-=!
А вот то же самое сообщение, закодированное снова:
Digest-a00bf11d-=:.?=:&!.?.1&-=:=?.?.=.?.!&=%!=-%@=!%~.=^#.1%%.!%+=:.~.@..==%&&1%~.1%@=?.@.!&=.!&@=:&1.==:=!.1&:
Видно, что дайджест у одного и того же сообщения совпадает, но шифр становится другим — шумовые символы добавляются произвольным соответствием и в произвольном порядке для каждого нового шифрования.
Сообщения обладают избыточностью, которая уменьшается по мере роста объема сообщения, в пределе доходя до 10% шума (для самых коротких сообщений шум достигает 90% и выше процентов), минимальная длина шифрованного сообщения — 116 символов. Один из некоторых минусов данного способа шифрования — увеличения кодированных сообщений как минимум в два раза.
Декодирование заключается в обратном переводе вида «кодовый символ» — исходный символ с вырезанием шума из сообщения. Что может быть в качестве ключа? В принципе, любая строка, уникальная для каждой пары вида адресат-получатель.
К примеру, если вы создаете мессенджер с шифрованием сообщений, в таком случае простейший вариант закрытого ключа может быть md5($user_id_1. $salt. $user_id_2), тогда ключ будет уникальный для каждого канала сообщений.
Комментарии (13)
rpiontik
02.10.2018 20:17+1Не совсем понял, а какую задачу Вы решаете? Чем SSL/TLS не угодил? Для WEB приложений.
berez
02.10.2018 20:17+1Шифруем текст:
Der korer allerede en anden programd?mon.
После дешифровки получаем рэзультат:
Der krer allerede en anden programdmon.
Чудесный шифер, ящетаю. :)
h0t_max
02.10.2018 20:35+3Постараюсь организовать конструктивную критику.
Итак, напишем собственную систему обратимого шифрования с приватным и публичным ключом, такую, которая будет обладать следующими признаками мало мальски защищенного криптографического алгоритма:
требования, которые вы указываете, не являются требованиями к алгоритму шифрования. Фактически шифр хорош, если у вас наличие зашифрованного текста (или пар открытый текст — шифртекст) не уменьшает неопределенность криптоаналитика. В Вашем случае это не так.
Для усложнения частотного анализа будем кодировать каждый исходный символ сообщения двумя символами шифра
Просто как пример того, что частотный анализ будет все-равно работать можете зашифровать большую последовательность одинаковых символов. Пример:
На счет
Другая сторона истины в том, что развитие какой-то области знаний происходит только при постоянном притоке свежих идей и оригинальных решений в ней.
Мне близка позиция Брюса Шнаера. Он говорит, что в мире и так много плохих систем, зачем делать еще одну. Очень рекомендую к прочтению его книгу Практическая криптография.
berez
02.10.2018 21:07+1Дополню.
1. То, что homoastricus называет «приватным ключом», на самом деле и является единственным ключом шифрования в его системе. «Публичный» ключ в этой системе — это всего лишь соль.
2. Автор путает кодирование и шифрование (отсюда, например, радостные утверждения, будто кодирование одного исходного символа двумя символами шифротекста есть борьба с частотным анализом). Если бы автор отвлекся от печатных символов и начал свою систему шифрования «из байтов в байты», было бы проще понять эту ошибку. А закодировать в печатный текст можно уже после шифрования. Благо, кодировок для этого придумано выше крыши: хочешь — хексами байты изображай, хочешь — Base64, а ежели совсем на хардкор тянет — есть ascii85.
3. Странный набор результирующих символов. Проблема в том, что строки, состоящие из сплошной пунктуации, не очень подходят для передачи по каналам связи методом копи-пасты. Прикиньте, сколько смайликов найдет в такой строке какой-нибудь мессенджер. :)
4. При анализе системы шифрования исходят из того, что все исходники есть у атакующей стороны. Все шифрование у автора построено вокруг одной таблицы пермутаций, которая строится по фиксированному хэшу (плюс какие-то прыжки вокруг присланной снаружи соли — лень было разбираться). А это значит, что атакующему достаточно выяснить «приватный ключ» (сиречь — единственный ключ шифрования), и он сможет прочесть всю переписку. Что-то мне подсказывает, что подобрать содержимое таблицы, имея энное количество перехваченных сообщений, вполне себе решаемая задача.flatscode
03.10.2018 04:47Господа, h0t_max, berez, я поражаюсь вашему спокойствию!
Данная поделка, вкупе с использованной терминологией и ложными утверждениями в статье, ничего кроме нецензурных слов не вызывают!
homoastricus, пишите статью про необратимое шифрование, это будет новое слово в науке.Zolg
03.10.2018 11:43ППКС
Автор секретный язык придумал, а вы на полном серьезе его лингвистическое несовершенство обсуждаете.
Единственная проблема — секретные языки обычно в младшем школьном возрасте изобретают, а автор вроде на школьника не похож.berez
03.10.2018 15:57Не скажу за h0t_max, а лично я всегда считаю человека небезнадежным, пока он не докажет обратное. Автор интересуется шифрованием — это хорошо. Автор берется реализовать самописную шифрульку — это тоже неплохо.
Плохо, что автор так и не смог найти внятных введений в криптографию. Нахватался где-то терминов, понял их как смог, написал что попало.
В дополнение к книге Брюса Шнайера рекомендую homoastricus купить и почитать
Книгу шифров Саймона Сингха. Написана очень легким языком, читается запоем. Просто и доходчиво объясняются базовые концепции криптографии. Пойдет в качестве введения и этакого исторического экскурса в криптографию. После нее книги Шнайера читаются и понимаются не в пример легче.
NeoCode
02.10.2018 22:32Одна из основных истин криптографии гласит, что не стоит изобретать чего-либо в этой сфере, если вы не профессионал.
Вот совершенно согласен. К сожалению, мои познания в высшей математике (необходимые для разработки чего-то типа асимметричного или полностью гомоморфного шифрования) далеки от идеальных, а школьные эксперименты типа шифрования на XOR (и даже с рандомным зашумлением) вряд ли будут кому интересны.
Гораздо интереснее другое. Есть немало проверенных и отлаженных алгоритмов шифрования, применяемых для самых разных целей: PGP, зашифрованные сеансы в сети, децентрализованные анонимные сети, блокчейн и т.д…
Пусть эти алгоритмы будут «черными ящиками», но с очень хорошим описанием того, в каких случаях их можно и нужно применять, а в каких — нельзя. Вот хочется хороший, качественный мануал такого типа.
Ну и качественная библиотека, где все эти алгоритмы собраны, тоже не помешает. Тут на опеннете проскакивала новость про библиотеку Tink от Google, в которой собраны некоторые примитивы шифрования. Вот по идее нужно что-то такое, и с хорошим мануалом «для чайников», где буквально разжеваны понятия и примеры применения.
SerafimArts
03.10.2018 00:58Эм, а разве не проще и на порядки надёжнее будет как-нибудь, на вскидку:
foreach ($chars as $i => $char) { yield \bin2hex($char >> \ord($key[$i % \strlen($key)])); }
Т.е. для каждого символа применяем сдвиг, равный одному из символов ключа. Сделать из этого по публичному+приватному ключу — дело 5ти минут, надо всего лишь привязать один к другому через любое хеширование.Zolg
03.10.2018 12:34На порядок надежнее будет использовать какую-либо криптобиблиотеку, или же, если уж хочется самому закодить на коленочке — реализовать TEA/XTEA.
Ассимитричную криптографию с открытым и закрытым (public & private) ключами на коленочке закодить посложнее, но авторское поделие к ней отношения не имеет. Собственно как и к криптографии в принципе.
Asikk
03.10.2018 10:14Если зашифровать
Error: Incorrect message found
И испортить шифр, то класс все равно его корректно декодирует
Zolg
Срочно делайте свой мессенджер с шифрованием и утехами.
Уполномоченным товарищам понравится.