Search code examples
c++xor

Porting XOR encryption code to PHP


I usually find my answer here somewhere, but I've been unable to find the solution from the existing questions. I apologize if I misssed an answer elsewhere..

This is my C++ code :

    char key[4] = "abc";

for (int temp = 0; temp < original.size(); temp++){
    encrypted += original[temp] ^ (int(key) + temp) % 255;
}
cout << int(key) << endl;
cout << "Encrypted data = " << encrypted << endl;

for (int temp = 0; temp < original.size(); temp++){
    unencrypted += encrypted[temp] ^ (int(key) + temp) % 255;
}

cout << "Unencrypted data = " << unencrypted << endl;

Which returns a long string of random characters (e.g. ♧).

And my attempt at translating, as to my understanding, the XOR encryption to PHP:

<?php
$input = "ONEWORD";
$encrypted = "";
$unencrypted = "";

$key = "abc";

$ascii = NULL;

for ($i = 0; $i < strlen($string); $i++) 
{ 
$ascii += ord($string[$i]); 
}


for($i = 0; $i < sizeof($input); $i++)
{
    $encrypted+= $input[$i] ^ ($ascii + $i) % 255;
}
echo($encrypted);
echo(ord($key));

    for($i = 0; $i < sizeof($input); $i++)
{
    $unencrypted+= $encrypted[$i] ^ ($ascii + $i) % 255;
}

echo($unencrypted);
?>

While this returns a simple 0970. I'm not quite sure where I went wrong, can anyone lead me in the right direction?

Thanks


Solution

  • This line in your C++ code is bogus:

        encrypted += original[temp] ^ (int(key) + temp) % 255;
    

    This doesn't do what you think it does. int(key) casts key to int. In this context key will decay to a pointer, so you're not actually getting the key at all, you're getting an integer representation of the pointer to the key.

    What you likely want is this:

        encrypted += char(original[temp] ^ key[temp % 3]);
    

    That will XOR the first character of the string with the first character of the key, the second character of the string with the second character of the key, and third character of the string with the third character of the key. Thereafter, it'll cycle through the three characters in the key, applying them to each character of the input in-turn.

    You need to make a similar change to your decryption code:

        unencrypted += char(encrypted[temp] ^ key[temp % 3]);
    

    In PHP, to work with individual character values, you need to use the ord operator to convert the characters to integers, and the chr operator to convert the integers back to characters.

        $encrypted += chr( ord( $input[$i] ) ^ ord( $key[$i % 3] ) );
    

    And likewise for decryption:

        $decrypted += chr( ord( $encrypted[$i] ) ^ ord( $key[$i % 3] ) );