Обратимое XOR шифрование текста со случайной гаммой

Обратимое XOR шифрование текста со случайной гаммой
просмотров: 344124 марта 2012 года

Однажды, при разработке сайта, появилась необходимость передавать данные в зашифрованном виде используя 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)

Василий Пупкин (31 июля 2013 года, 14:52:43)

Добавьте пожалуйста пример шифрования на JavaScript!

Алекса (5 июня 2016 года, 07:59:51)

Вот, оно! А вот можно как нибудь добавить соль к XOR’у?

Что скажем?