JSON deconding返回NULL,错误:控制字符错误,可能编码错误

时间:2016-01-04 15:12:41

标签: php mysql json encryption encoding

因此,为了保护数据库(MySQL)中的用户数据,我将敏感(会话,IP,用户ID等)数据存储在数组中,将其编码为JSON,并存储在数据库中加密的JSON字符串。

在检索数据时,我使用该记录的密钥个人再次解密数据,并再次将JSON解码为数组。或者是我正计划做的事情。

问题是在解码JSON字符串时,它会以静默方式失败并返回NULL。当收到最后一个JSON错误时,它表示"控制字符错误,可能编码错误"

所以让我们来完成这个过程。 (当然简化) 简单地编码和解码数组工作正常,并不令人惊讶:

$data = array("test" => 1, "try" => "foo");
$json = json_encode($data);
$result = json_decode($json, true);

var_dump($data);
var_dump($json);
var_dump($result);

输出:

array(2) { ["test"]=> int(1) ["try"]=> string(3) "foo" } 
string(22) "{"test":1,"try":"foo"}" 
array(2) { ["test"]=> int(1) ["try"]=> string(3) "foo" }

当我尝试使用包含的编码时:

$data = array("test" => 1, "try" => "foo");
$json = json_encode($data);
$randKey = "someStrongKey";
$encoded = encrypt($json, $randKey);
$decoded = decrypt($encoded, $randKey);
$result = json_decode($decoded, true);

var_dump($data);
var_dump($json);
var_dump($encoded);
var_dump($decoded);
var_dump($result);

输出:

array(2) { ["test"]=> int(1) ["try"]=> string(3) "foo" } 
string(22) "{"test":1,"try":"foo"}" 
string(44) "k4a8q/zICngAoxtbhpnsf23J89M5Lmc14DBjpxG098M=" 
string(32) "{"test":1,"try":"foo"}" 
NULL

使用的加密和解密功能:

function encrypt($data, $key) {
   $salt = "strongsalthere";
   $key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
   $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
   $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
   $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv));
   return $encrypted;
}

function decrypt($data, $key) {
   $salt = "strongsalthere";
   $key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
   $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
   $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
   $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv);
   return $decrypted;
}

正如您所看到的,当我加密数据时,然后解密它。我检索完全相同的字符串。但由于某种原因,JSON无法解码并且获得最后一个JSON错误显示"控制字符错误,可能错误编码"。

我在这里缺少什么?我注意到原始的JSON字符串只有22个字符,解码的字符串有32个字符。这是什么?我猜这是问题的一部分。

解决方案

我无法回答我自己的问题,因为它被标记为重复,但我相信更多的人会遇到这个问题而且所提到的帖子是没有出现的当我自己搜索问题时,我会在这里添加解决方案。

显然,mcrypt和decrypt函数为数据添加零填充,使其成为块长度的精确倍数。因此,如果打印出字符串,则此零填充将添加到数据中,但不可见(因为它是二进制填充)。 (这就是为什么String输出看起来相同但字节长度与我前面提到的不同。)

JSON解码函数无法处理那些零填充字节,因此它只返回null。

要解决此问题,必须首先在解码JSON之前先从字符串中删除此零填充。

$jsonString = rtrim($jsonString, "\0");

因此,当您想使用JSON将解密数据转换为数组时。

$data = array("test" => 1, "try" => "foo");
$json = json_encode($data);
$randKey = "someStrongKey";
$encoded = encrypt($json, $randKey);
$decoded = decrypt($encoded, $randKey);
$decoded = rtrim($decoded, "\0");
$result = json_decode($decoded, true);

这将产生预期的输出并再次创建原始数组。

0 个答案:

没有答案