Xor encryption in PHP

六眼飞鱼酱① 提交于 2019-12-05 03:45:15

How i did it, might help someone ...

$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);
}

I think you might have a few problems here, I've tried to outline how I think you can fix it:

  • You need to use ord(..) to get the ASCII value of a character so that you can represent it in binary. For example, try the following:

    printf("%08b ", ord('A')); // outputs "01000001"
    
  • I'm not sure how you do an XOR cipher with a multi-byte key, as the wikipedia page on XOR cipher doesn't specify. But I assume for a given key like "123", your key starts "left-aligned" and extends to the length of the text, like this:

    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_]]"
    

    Which encrypts 'hello' width the key '12312'.

There's no guarantee that the result of the XOR operation will produce a printable character. If you give us a better idea of the reason you're doing this, we can probably point you to something sensible to do instead.

I believe you are faced with console output and encoding problem rather than XOR-related. Try to output results of xor function in a text file and see a set of generated characters. I believe HEX editor would be the best choice to observe and compare a generated characters set.

Basically to revert text back (even numbers are in) you can use the same function:

var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);

Based on the fact that you're getting xor_this( xor_this('123') ) = '123', I am willing to guess that this is merely an output issue. You're sending data to the browser, the browser is recognizing it as something which should be rendered in HTML (say, the first half dozen ASCII characters). Try looking at the page source to see what is really there. Better yet, iterate through the output and echo the ord of the value at each position.

Use this code, it works perfect

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);
}

Try this:

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

If one of the two operands is an integer, PHP casts the other to an integer and XORs them for a numeric result.

Alternatively, you could use this:

$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)))};
}

note: it probably will create some weird characters...

Despite all the wise suggestions, I solved this problem in a much simpler way:

I changed the key! It turns out that by changing the key to something more like this:

$key = 'ISINUS0478331006';

...it will generate an obfuscated output of printable characters.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!