15

I am studying encryption. And I got a problem like this:

After I XOR plaintext with a key, I get a crypt, "010e010c15061b4117030f54060e54040e0642181b17", as hex type. If I want to get plaintext from this crypt, what should I do in PHP?

I tried convert it to string/int and after that take them to XOR with the key (three letters). But it doesn't work.

This is the code:

function xor_this($string) {

    // Let's define our key here
    $key = 'fpt';

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

function strToHex($string)
{
    $hex = '';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

function hexToStr($hex)
{
    $string = '';
    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}

$a = "This is the test";
$b = xor_this($a);
echo xor_this($b), '-------------';
//
$c = strToHex($b);
$e = xor_this($c);
echo $e, '++++++++';
//
$d = hexToStr($c);
$f = xor_this($d);
echo $f, '=================';

And this is the result:

This is the test-------------

PHP Notice: Uninitialized string offset: 29 in C:\ Users\Administrator\Desktop\test.php on line 210 PHP Stack trace: PHP 1. {main}() C:\Users\Administrator\Desktop\test.php:0 PHP 2. xor_this() C:\Users\Administrator\Desktop\test.php:239

Notice: Uninitialized string offset: 29 in C:\Users\Administrator\Desktop\test.p hp on line 210

Call Stack: 0.0005 674280 1. {main}() C:\Users\Administrator\Desktop\test.php:0 0.0022 674848 2. xor_this() C:\Users\Administrator\Desktop\test.php:23 9

UBE^A►WEAVA►WEAV@◄WEARAFWECWB++++++++

This is zs$fs☺=================

Why? The "UBE^A►WEAVA►WEAV@◄WEARAFWECWB++++++++" is the result, which I got trouble in my real work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JoeNguyen
  • 1,049
  • 2
  • 11
  • 15

3 Answers3

27

Try this:

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) && $i<strlen($text)); $j++,$i++)
        {
            $outText .= $text{$i} ^ $key{$j};
            //echo 'i=' . $i . ', ' . 'j=' . $j . ', ' . $outText{$i} . '<br />'; // For debugging
        }
    }
    return $outText;
}

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

$textToObfuscate = "Some Text 12345";
$obfuscatedText = xor_this($textToObfuscate);
$restoredText = xor_this($obfuscatedText);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
One Man Crew
  • 9,420
  • 2
  • 42
  • 51
  • 1
    It doesn't work. Cause my key is only 3 letters, so the Crypt must be divide into group of 3 before xor. And one more thing, the Crypt is hexa, so we must convert it firstly - I think that but not sure - It is my problem :) – JoeNguyen Feb 03 '13 at 14:48
  • 1
    Oh, I understood your code. This code doesn't care the length of key. But the crypt is a hexa, do we need to convert it before xor with key? – JoeNguyen Feb 03 '13 at 14:56
  • You can use this http://ditio.net/2008/11/04/php-string-to-hex-and-hex-to-string-functions/ – One Man Crew Feb 03 '13 at 14:59
  • I tried and it work with string does not have "space". with the space, it got problem. – JoeNguyen Feb 03 '13 at 15:03
  • @OneManCrew You have a small error $obfuscatedText = $xor_this($textToObfuscate); should be $obfuscatedText = xor_this($textToObfuscate);.A good encryption code,keep up the good work. – Vicks Sep 18 '14 at 09:48
  • 1
    Note that the current implementation will run in an infinite loop if the key is an empty string (relevant especially if the function is modified to receive the key as a parameter). – Dvd848 Dec 17 '19 at 19:19
20

Even easier:

function xor_string($string, $key) {
    for($i = 0; $i < strlen($string); $i++) 
        $string[$i] = ($string[$i] ^ $key[$i % strlen($key)]);
    return $string;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
onetiger
  • 311
  • 2
  • 7
2

Based on the code above i created 2 functions to xor encode a JSON string using javascript and then decode it on server side using PHP.

!!! Important: If you will have characters different from ASCII(like Chinese, Cyrillic, Symbols...) in your JSON string, you must either write some code in PHP or JS to fix how these characters are encoded/decoded (ord/chr in PHP produce different results in comparison with JS charCodeAt/String.fromCharCode) or just base64_encode the JSON string and after that xor encode it.

Personally i use xor_string(base64_encode(JSON.stringify(object)), 'xor_key') in JS and on PHP side:

$json = json_decode(base64_decode(
                        xor_string(file_get_contents("php://input"), 'xor_key')
                    ),
        true);

PHP:

function xor_string($string, $key) {
    $str_len = strlen($string);
    $key_len = strlen($key);

    for($i = 0; $i < $str_len; $i++) {
        $string[$i] = $string[$i] ^ $key[$i % $key_len];
    }

    return $string;
}

Javascript:

function xor_string(string, key) {
    string = string.split('');
    key = key.split('');
    var str_len = string.length;
    var key_len = key.length;
    var String_fromCharCode = String.fromCharCode;

    for(var i = 0; i < str_len; i++) {
        string[i] = String_fromCharCode(string[i].charCodeAt(0) ^ key[i % key_len].charCodeAt(0));
    }

    return string.join('');
}
Stalingrad
  • 159
  • 1
  • 8
  • Of course most of the world is non-ASCII so this is very limited. Copnsider a soltion that it generally usable. – zaph Feb 18 '17 at 23:52
  • It's usable, i mentioned that i use to encode the string to base64 and then XOR it, i wouldn't post this if it wouldn't work – Stalingrad Feb 19 '17 at 00:26