Одна из основных истин криптографии гласит, что не стоит изобретать чего-либо в этой сфере, если вы не профессионал. Отчасти это действительно так, ибо все лучшее давно уже изобретено, выстрадано и используется не один десяток лет в сфере информационных технологий. Другая сторона истины в том, что развитие какой-то области знаний происходит только при постоянном притоке свежих идей и оригинальных решений в ней.
По очевидным причинам не будем замахиваться на гигантов индустриальной криптографии вроде AES, а погрузимся, так сказать, в собственные криптографические изыскания с блекджеком и утехами.
Отчасти потому, что это интересно, отчасти потому, что моделируя что-то свое и сравнивая это с признанными стандартами, наглядно видишь контраст, эффективные решения и откровенные упущения, понимаешь, к чему можно стремиться для повышения эффективности.
Но довольно уже воды.
Допустим, наше веб-приложение написано на php, нуждается в обратимом шифровании и мы считаем, что в силах написать свою систему шифра.
Итак, напишем собственную систему обратимого шифрования с приватным и публичным ключом, такую, которая будет обладать следующими признаками мало мальски защищенного криптографического алгоритма:
Итак, что получилось.
Собственно говоря, итоговый результат посмотреть можно здесь
Класс SymCoder
Класс SymCoder включает в себя методы шифрования и дешифрования.
Шифрование осуществляет метод code(), принимающий на входе исходное сообщение.
Здесь сообщение по сгенерированной таблице соответствия в tab_coded создает зашифрованное сообщение, разбавленное по краям и внутри шумовыми символами.
Шумовые символы кстати уникальны для каждого канала отправитель-адресат, так как генерируются используя ключ канала, но не уникальны для сообщений. Используемые для шифрования символы в code_symbols представляют собой некоторые знаки пунктуации и символы вида %, @ и т.п.
На каждый кодируемый символ приходится два символа из code_symbols по понятным причинам, что их в несколько раз меньше, чем кодируемых символов.
Таблица соответствия create_tab_coded строится используя трансляцию хеша ключа сообщения в массив с количеством элементов, равным количеству элементов в массиве кодовых символов. Позиция начала обхода двухсимвольных кодов также всегда различна и связана с ключом канала. Это дает возможность быть уверенным, что алгоритм обхода кодируемых символов и соответствия им кодовых символов всегда (ну или гарантированно часто) будет различным.
К примеру, сообщение «привет, мир» будучи закодированным, выглядит вот так:
А вот то же самое сообщение, закодированное снова:
Видно, что дайджест у одного и того же сообщения совпадает, но шифр становится другим — шумовые символы добавляются произвольным соответствием и в произвольном порядке для каждого нового шифрования.
Сообщения обладают избыточностью, которая уменьшается по мере роста объема сообщения, в пределе доходя до 10% шума (для самых коротких сообщений шум достигает 90% и выше процентов), минимальная длина шифрованного сообщения — 116 символов. Один из некоторых минусов данного способа шифрования — увеличения кодированных сообщений как минимум в два раза.
Декодирование заключается в обратном переводе вида «кодовый символ» — исходный символ с вырезанием шума из сообщения. Что может быть в качестве ключа? В принципе, любая строка, уникальная для каждой пары вида адресат-получатель.
К примеру, если вы создаете мессенджер с шифрованием сообщений, в таком случае простейший вариант закрытого ключа может быть md5($user_id_1. $salt. $user_id_2), тогда ключ будет уникальный для каждого канала сообщений.
По очевидным причинам не будем замахиваться на гигантов индустриальной криптографии вроде 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), тогда ключ будет уникальный для каждого канала сообщений.