Kurieita
Kurieita

Reputation: 93

PHP JSON Decode erroring with valid JSON

I am trying to decode a simple JSON string and the format to make it look correct. I actually copied the string and decode is with the same algorithm but without all the extra code and it worked fine.

print_r(json_decode('{"user_id":1,"issused":"2016-02-24 04:40:17","expire":"2016-03-02 04:40:17"}'));

That worked. But when I do

$hash = Hash::salt(32);
$issused = date('Y-m-d H:i:s');
$expire = date('Y-m-d H:i:s', strtotime('+1 week'));
$data = array('user_id' => 1, 'issused' => $issused, 'expire' =>     $expire);
$encrypt = Cipher::encrypt(json_encode($data), $hash);
$decrypt = Cipher::decrypt($encrypt, $hash);
echo $encrypt;
echo "<br><br>";
echo $decrypt;
echo "<br><br>";
print_r(json_decode($decrypt));

Where $decrypted is the valid formated JSON that I posted above. When I used:

echo json_last_erro();

It gave me an output of 3 which is JSON_ERROR_CTRL_CHAR

Any idea why this isn't being decoded correctly?

EDIT Here is how I am encrypting data.

class Cipher {
public static function encrypt($string, $hash) {
    $size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($size, MCRYPT_RAND);
    $encrypted = mcrypt_encrypt(MCRYPT_BLOWFISH, $hash, utf8_encode($string), MCRYPT_MODE_ECB, $iv);
    //$encoded = urlencode($encrypted);
    $encoded = base64_encode($encrypted);
    return $encoded;
}

public static function decrypt($string, $hash) {
    //$decoded = urldecode($string);
    $decoded = base64_decode($string);
    $size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($size, MCRYPT_RAND);
    $decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, $hash, $decoded, MCRYPT_MODE_ECB, $iv);
    return $decrypted;
}

}

Here how I am creating the salt.

public static function salt($length) {
    return mcrypt_create_iv($length); //base64_encode(openssl_random_pseudo_bytes($length));
}

Upvotes: 3

Views: 272

Answers (1)

Bill Croft
Bill Croft

Reputation: 76

The extra control characters (\0) are due to the cypher block padding. From the mcrypt_decrypt docs

data

  • The data that will be decrypted with the given cipher and mode. If the size of the data is not n * blocksize, the data will be padded with '\0'.

You can pad the input for the block size yourself in the encrypt and then remove the extra padding in decrypt() or you can trim the trailing zero bytes from the decoded message doing the below.

$decrypt = trim($decrypt, "\0");

Upvotes: 2

Related Questions