Обратимое XOR шифрование текста со случайной гаммой
Однажды, при разработке сайта, появилась необходимость передавать данные в зашифрованном виде используя PHP. Конечно же сразу пришла мысль использовать mcrypt который уже есть на PHP... Но эта идея сразу же отпала, поскольку не на всех хостингах этот модуль установлен.
Немного поразмыслив, оказалось, что пожалуй самым надежным и просто реализуемым методом шифрования будет XOR-метод (суммирование по модулю).
Немного расскажу как вообще работает XOR:
XOR - это побитовое сложение по модулю (с инвертированием при переполнении), например, 1+1=0 т.к. 1 - максимальное значение.
Все варианты:
0+0=0
0+1=1
1+1=0
Уникальность сложения по модулю состоит в его обратимости! Т.е. если придумать некоторое слово-код (назовем его гаммой) и выполнить XOR 2 раза к открытому тексту - то получим тот же открытый текст.
Пример работы XOR
Допустим, у нас есть открытый текст - "denik.od"
Придумаем для него гамму: "12345678" (гамма должна быть равной длине текста, т.к. мы весь текст хотим зашифровать)
Конкретный пример рассмотрим на первых 2-х байтах "de" (представим их в двоичной системе):
Имеем | d 1 |
e 2 |
Это же, только в двоичной системе |
1100100 0110001 |
1100101 0110010 |
Результат XOR | 1010101 | 1010111 |
Результат XOR (символы) |
U | W |
Для расшифровки, просто применим XOR еще раз:
Имеем | U 1 |
W 2 |
Это же, только в двоичной системе |
1010101 0110001 |
1010111 0110010 |
Результат XOR | 1100100 | 1100101 |
Результат XOR (символы) |
d | e |
В результате мы получили наши первые 2 байта (de). Точно так же делается со всем текстом.
Все остальные усложнения уже заложены в методах генерации этой самой гаммы. Есть много способов ее генерации, но в основу своего способа, я заложил функцию sha1 (создание HEX хеша).
Логика проста, мы составляем гамму длиной в кодируемый текст примерно так:
$gamma .= sha1($passw . $gamma);
Полный пример для PHP:
function strcode($str, $passw="")
{
$salt = "Dn8*#2n!9j";
$len = strlen($str);
$gamma = '';
$n = $len>100 ? 8 : 2;
while( strlen($gamma)<$len )
{
$gamma .= substr(pack('H*', sha1($passw.$gamma.$salt)), 0, $n);
}
return $str^$gamma;
}
Использование:
$txt = "Hello XOR encode!";
$txt = base64_encode(strcode($txt, 'mypassword'));
echo $txt;
/* result - ZOHdWKf+cf7vAwpJNfSJ8s8= */
$txt = "ZOHdWKf+cf7vAwpJNfSJ8s8=";
$txt = strcode(base64_decode($txt), 'mypassword');
echo $txt;
/* result - Hello XOR encode! */
Комментарии (2)
Добавьте пожалуйста пример шифрования на JavaScript!
Вот, оно! А вот можно как нибудь добавить соль к XOR’у?