Xor шифрование в PHP - PullRequest
       58

Xor шифрование в PHP

8 голосов
/ 26 сентября 2011

Я новичок в шифровании Xor, и у меня возникли проблемы со следующим кодом:

function xor_this($string) {

// Let's define our key here
 $key = ('magic_key');

 // Our plaintext/ciphertext
 $text =$string;

 // Our output text
 $outText = '';

 // Iterate through each character
 for($i=0;$i<strlen($text);)
 {
     for($j=0;$j<strlen($key);$j++,$i++)
     {
         $outText .= $text{$i} ^ $key{$j};
         //echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
     }
 }  
 return $outText;
}

Когда я запускаю это, оно работает для обычных строк, например, «собака», но только частично работает для строк, содержащих числа, например, «12345».

Для демонстрации ...

xor_this('dog') = 'UYV'

xor_this('123') = ''

Также интересно отметить, что xor_this( xor_this('123') ) = '123', как я и ожидаю. Я почти уверен, что проблема кроется где-то в моем шатком понимании побитовых операторов, ИЛИ, возможно, способа, которым PHP обрабатывает строки, содержащие числа. Бьюсь об заклад, есть кто-то умный, который точно знает, что здесь не так. Спасибо.

РЕДАКТИРОВАТЬ # 1: Это не «шифрование». Я думаю, что запутывание является правильным термином, который я и делаю. Мне нужно передать код, содержащий неважные данные от пользователя, чтобы они не могли легко его изменить. Они завершают задание по времени в автономном режиме и отправляют свое время в онлайн-табло с помощью этого кода. В автономном режиме запутывает свое время (в миллисекундах). Мне нужно написать скрипт для получения этого кода и вернуть его обратно в строку, содержащую их время.

Ответы [ 9 ]

4 голосов
/ 24 января 2013

Как я это сделал, может кому-то помочь ...

$msg = 'say hi!';
$key = 'whatever_123';

// print, and make unprintable chars available for a link or alike.
// using $_GET, php will urldecode it, if it was passed urlencoded
print "obfuscated, ready for url: " . urlencode(obfuscate($msg, $key)) . "\n";
print "deObfuscated: " . obfuscate(obfuscate($msg, $key), $key);


function obfuscate($msg, $key) {
    if (empty($key)) return $msg;
    return $msg ^ str_pad('', strlen($msg), $key);
}
3 голосов
/ 26 сентября 2011

Я думаю, что у вас может быть несколько проблем здесь, я попытался обрисовать, как, я думаю, вы можете это исправить:

  • Вам нужно использовать ord(..), чтобы получить значение ASCII символа, чтобы вы могли представить его в двоичном виде.Например, попробуйте следующее:

    printf("%08b ", ord('A')); // outputs "01000001"
    
  • Я не уверен, как вы делаете шифр XOR с многобайтовым ключом, как страница википедии на шифре XOR не указывает.Но я предполагаю, что для данного ключа, такого как «123», ваш ключ начинает «выравниваться по левому краю» и распространяется на длину текста, например:

    function xor_this($text) {
        $key = '123';
        $i = 0;
        $encrypted = '';
        foreach (str_split($text) as $char) {
            $encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
        }
        return $encrypted;
    }
    print xor_this('hello'); // outputs "YW_]]"
    

    Который шифрует 'hello' ширину ключа '12312'.

1 голос
/ 13 марта 2014

Используйте этот код, он отлично работает

function scramble($inv) {
  $key=342244;  // scramble key
  $invarr=str_split($inv);
  for($index=0;$index<=strlen($inv)-1;$index++) {
    srand($key);
    $var=rand(0,255);
    $res=$res.(chr(ord($var)) ^ chr(ord($invarr[$index])));
    $key++;
  }
  return($res);
}
1 голос
/ 26 сентября 2011

Исходя из того, что вы получаете xor_this( xor_this('123') ) = '123', я хочу предположить, что это всего лишь выходной вопрос.Вы отправляете данные в браузер, браузер распознает их как нечто, что должно быть отображено в HTML (скажем, первые полдюжины символов ASCII).Попробуйте посмотреть на странице источника, чтобы увидеть, что на самом деле там.Еще лучше, перебрать вывод и повторить ord значения в каждой позиции.

1 голос
/ 26 сентября 2011

Я полагаю, что вы столкнулись с проблемой вывода на консоль и кодирования, а не с XOR.Попробуйте вывести результаты функции xor в текстовый файл и увидеть набор сгенерированных символов.Я считаю, что HEX-редактор был бы лучшим выбором для наблюдения и сравнения сгенерированного набора символов.

В основном для возврата текста назад (четные числа в) вы можете использовать ту же функцию:

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
1 голос
/ 26 сентября 2011

Нет гарантии, что в результате операции XOR будет напечатан печатный символ.Если вы дадите нам лучшее представление о причине, по которой вы это делаете, мы, вероятно, можем указать вам на что-то разумное, чтобы сделать вместо этого.

0 голосов
/ 29 сентября 2011

Несмотря на все мудрые предложения, я решил эту проблему гораздо проще:

Я сменил ключ! Оказывается, изменив ключ на что-то более похожее на это:

$key = 'ISINUS0478331006';

... генерирует запутанный вывод печатных символов.

0 голосов
/ 26 сентября 2011
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
    $outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}

примечание: это, вероятно, создаст некоторые странные символы ...

0 голосов
/ 26 сентября 2011

Попробуйте:

$outText .= (string)$text{$i} ^ (string)$key{$j};

Если один из двух операндов является целым числом, PHP преобразует другой в целое число и XOR их для числового результата.используйте это:

$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
...