json_decode returns NULL on string that has passed

2019-09-04 11:11发布

问题:

I am trying to secure information on my database and the standard type of data is JSON and I just wrote some simple mcrypt functions that encrypt and decrypt any text, here they are:

function encrypt($key, $data){
    $encrypted_data = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, $data, MCRYPT_ENCRYPT);
    return base64_encode($encrypted_data);
}

function decrypt($key, $encryptedData){
    $decrypt = mcrypt_cbc(MCRYPT_RIJNDAEL_192, $key, base64_decode($encryptedData), MCRYPT_DECRYPT);
    return $decrypt;
}

I have a valid JSON string and I've tested the json_decode without passing through encryption, and it works. But when I encrypt then decrypt it then try to json_decode it only returns NULL.

Right now I'm just debugging it in a simple script here it is:

include("coreFunctions.php");

$arr = '{"number":"4646464646","type":"home"}';

$key = "ladida";
$locked = encrypt($key, $arr);

var_dump($locked);
var_dump(json_decode(decrypt($key, $locked), true));

I have verified the output of decrypt is a the SAME as it went in.

Can anyone tell me why this is happening?

UPDATE
I've discovered the strlen() before and after is different. So how can I either make sure that it stays the same throughout the encryption process or fix it after it's done?

回答1:

bin2hex reads:
033303539222c2274797065223a22686f6d65227d00000000000000000000

That means you have trailing NUL bytes in the decrypted string. This happens because the mcrybt_cbc operates block-wise. It'll fill up input and output to multiples of 16 (or 24) bytes to do so. (The output might sometimes even contain garbage; hencewhy a length field often occampanies most encryption schemes / container formats.)

In your ase you can get away with applying rtrim after the decryption. Or more exactly:

 json_decode(rtrim(decrypt($key, $locked), "\0"), true);