JRunner
JRunner

Reputation: 1447

How do I perform XOR encryption in PHP?

I am trying to perform XOR encryption in PHP and I am having a lot of difficulty finding what script produces the correct output. I first used http://snipplr.com/view/8421/xor-encryptdecrypt/ script, and I altered it so it DOES NOT return the encrypted text as base64 encoded. I also removed it from a class. Here's my code:

$key = "My key";

function get_rnd_iv($iv_len)
{
    $iv = '';
    while ($iv_len-- > 0)
    {
        $iv .= chr(mt_rand() & 0xff);
    }
    return $iv;
}

function encrypt($plain_text, $iv_len = 16)
{
    $plain_text .= "\x13";
    $n = strlen($plain_text);
    if ($n % 16)
    {
        $plain_text .= str_repeat("\0", 16 - ($n % 16));
        $i = 0;
        $enc_text = get_rnd_iv($iv_len);
        $iv = substr($key ^ $enc_text, 0, 512);
        while ($i < $n)
        {
            $block = substr($plain_text, $i, 16) ^ pack('H*', sha1($iv));
            $enc_text .= $block;
            $iv = substr($block . $iv, 0, 512) ^ $key;
            $i += 16;
        }
        //return base64_encode($enc_text);
        return $enc_text;
    } else {}
}

function decrypt($enc_text, $iv_len = 16)
{
    //$enc_text = base64_decode($enc_text);
    $n = strlen($enc_text);
    $i = $iv_len;
    $plain_text = '';
    $iv = substr($key ^ substr($enc_text, 0, $iv_len), 0, 512);
    while ($i < $n)
    {
        $block = substr($enc_text, $i, 16);
        $plain_text .= $block ^ pack('H*', sha1($iv));
        $iv = substr($block . $iv, 0, 512) ^ $key;
        $i += 16;
    }
    return stripslashes(preg_replace('/\\x13\\x00*$/', '', $plain_text));
}

$enc = encrypt('text');
echo 'Encrypted: '.$enc.'<br />';
echo 'Decrypted: '.decrypt($enc);

Now, when I run this, I get:

Encrypted: ¥Õlµê®M²:Ýë??ÞÂ=粸 È,ñ ™ÑÂÔ ¹
Decrypted: text

EDIT:

Each time I run, I get a different output?!

However, the following sites produce results completely different from that snippet: http://www.abcel-online.com/tools.php?id=decrypt http://th.atguy.com/mycode/xor_js_encryption/

I also tried the code from this site: http://www.go4expert.com/forums/showthread.php?t=5555

Please tell me which one is correct, and what I'm doing wrong.

Upvotes: 1

Views: 791

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 93988

You are using a random IV, which is explictly used to generate different cipher text for each run of the function. This is to make sure you don't leak information about the plain text. E.g. otherwise encrypting the word "yes" twice would result in the same cipher text. Note that you may still have a leak regarding the size of the cipher text, which is related to the size of the plain text.

Upvotes: 1

Related Questions