Eamonn
Eamonn

Reputation: 1320

PHP AES encryption charset issue

I want to be able to retrieve data from server B, in an encrypted form, and decrypt it locally on server A.

On server A, I have a page with form inputs for a key value and a filename value, and the form posts to the same page. Once the values are inputted, I take the filename value and I build an fopen string to Server B, read the file's text via fgets, and return it to the AES class, using the key value to decrypt it.

The form page on server A is utf-8 encoded by means of a meta charset tag. The file on server B is a utf-8 encoded txt file.

When just dealing with local values (not using the form or anything), everything works fine:

$original = "this is my string";
$original_encrypted = $aes->encrypt($original);
$return = "<p>Original, encrypted: ".$original_encrypted."</p>";
$return.= "<p>Original: ".$aes->decrypt($original_encrypted)."</p>";
echo  $return;

//prints:
Original, encrypted: ѶIQ��SҨ�$��� ,O�������~ f
Original: this is my string

If, however, I take that encrypted string ѶIQ��SҨ�$��� ,O�������~ f and place it in my txt file on server B:

function retrieve_data($filename) {
    //... some validation
    $file=fopen("http://serverB/authorisation/logs/$filename.txt","r");
        while (($line = fgets($file)) !== false) {
            $parts.=stripslashes(trim($line));
        }
    fclose($file);
    return $parts;
}

//... some key validation
$z = "A3C56F83425746B4D62F984".$key; // 256-bit key
$aes = new AES($z);

$data = retrieve_data(stripslashes(trim($_POST['filename'])));
$return = "<p>Remote, Encrypted, Text: ".$data."</p>";
$return.= "<p>Now Plain Text: ".$aes->decrypt($data)."</p>";
echo $return;

//prints:
Remote, Encrypted, Text: ѶIQ��SҨ�$��� ,O�������~ f

Now Plain Text: B\�%;�`��]��\mb���q�)� �E�������l�����P�V+c�Ah�@ƶ>yq

Why would this be so? Given the same encrypted string, I'm getting two different outputs. I can only imagine there is some issue with the charset that is changing values somewhere along the way.

If I change my form page's encryption to ISO-8859-1, the encrypted string becomes ѶIQ’°SÒ¨á$«Îà ,OþÆÿ‡ÿè~ f. When I try to change the encoding of the remote txt file to ISO, and copy this string there, cPanel tells me that some of the characters are incompatible with ISO and boots me back to UTF-8. I then tried leaving serverA as ISO, but casting mb_convert_encoding or utf8-encode / utf8-decode on the incoming / outgoing data, but no working result. Any ideas?

Upvotes: 1

Views: 1699

Answers (1)

deceze
deceze

Reputation: 522500

The encrypted string is pseudo-random binary noise. It has no meaning as visible characters, because it doesn't represent any text encoding. If you display the string as characters, you'll get some random garbage which may or may not be missing individual bytes or have altered characters. If you copy and paste this into another file, there's no guarantee you're getting the same binary data back.

Don't treat the encrypted string as a readable piece of text. Instead write it into a file, copy that file and don't touch it. If you need the binary data as a copy-and-pasteable string, base64_encode it.

Upvotes: 1

Related Questions