Xor шифрование в PHP
Я новичок в шифровании 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 ответов
Несмотря на все мудрые предложения, я решил эту проблему гораздо проще:
Я изменил ключ! Оказывается, изменив ключ на что-то более похожее на это:
$key = 'ISINUS0478331006';
... он будет генерировать запутанный вывод печатных символов.
Как я это сделал, может кому-то помочь...
$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);
}
Я думаю, что у вас может быть несколько проблем здесь, я попытался обрисовать, как, я думаю, вы можете это исправить:
Вам нужно использовать
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'
,
Я считаю, что вы столкнулись с проблемой вывода на консоль и кодирования, а не с XOR. Попробуйте вывести результаты функции xor в текстовый файл и посмотрите набор сгенерированных символов. Я считаю, что HEX-редактор будет лучшим выбором для наблюдения и сравнения созданного набора символов.
В основном, чтобы вернуть текст обратно (даже четные числа), вы можете использовать ту же функцию:
var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
Нет никакой гарантии, что результат операции XOR приведет к печатному символу. Если вы дадите нам лучшее представление о причине, по которой вы это делаете, мы, вероятно, можем указать вам на что-то разумное, чтобы сделать вместо этого.
Используйте этот код, он отлично работает
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);
}
Исходя из того, что вы получаете xor_this( xor_this('123') ) = '123'
Я готов предположить, что это всего лишь выходной вопрос. Вы отправляете данные в браузер, браузер распознает их как нечто, что должно быть отображено в HTML (скажем, первые полдюжины символов ASCII). Попробуйте посмотреть на странице источника, чтобы увидеть, что на самом деле там. Еще лучше, перебрать вывод и повторить ord
значения в каждой позиции.
Попробуй это:
$outText .= (string)$text{$i} ^ (string)$key{$j};
Если один из двух операндов является целым числом, PHP преобразует другой в целое число и XOR их для числового результата.
В качестве альтернативы вы можете использовать это:
$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
$outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}
примечание: это, вероятно, создаст некоторые странные персонажи...