Javascript的JSON.stringfy和PHP的json_encode一样吗?
Is Javascript's JSON.stringfy the same as PHP's json_encode?
我正在尝试使用 JavaScript(CryptoJS 库)和 PHP(内置 HMAC 函数)对字符串化数据进行 HMAC SHA256 哈希。我担心 JavaScript JSON.stringify 不会 consistent/identical 到 PHP json_encode() 函数。有没有更好的方法来对数据进行这种字符串化 (object/array)?
这是我的测试,有效。但是,我担心代码可能遇到的西班牙字符和其他 encodings/entities。
<h1>Testing HMAC Javascript to PHP Comparison</h1>
<br><br>
<div id="php_mac">
<?php
// Testing HMAC
$security_key = '0123456789';
$obj = array(
'field1' => 1,
'field2' => '2',
'field3' => "'",
);
// Calculate HMAC SHA256
$str_data = json_encode($obj);
echo "PHP str_data: ".$str_data."<br>";
$hash = hash_hmac('sha256', $str_data, $security_key, true);
$hashInBase64 = base64_encode($hash);
echo "PHP hashInBase64: ".$hashInBase64;
?>
</div>
<br><br>
<div id="javascipt_hmac">
<div id="javascript_str_data"></div>
<div id="javascript_hashInBase64"></div>
<script>
var security_key = '0123456789';
var obj = {
'field1': 1,
'field2': '2',
'field3': "'",
};
// Create security hash based on posted data
var str_data = JSON.stringify(obj);
$('#javascript_str_data').html('str_data: '+str_data);
// Using CryptoJS to HMAC SHA256 the str_data
var hash = CryptoJS.HmacSHA256(str_data, security_key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
$('#javascript_hashInBase64').html('JS hashInBase64: '+hashInBase64)
</script>
</div>
其他想法:我担心 spacing/quoting 与 JSON 方法的差异。也许我应该循环遍历 object/array 并仅使用 "values" 来生成要进行 HMAC 处理的数据字符串?假设这可以保持为单个 array/object,那应该会产生一个一致的 "values" 字符串。但是,那么你如何保持一致的顺序。我假设它可以先按键订购。
正如@Pointy 在评论中提到的,JSON.stringify
和 json_encode
的输出在两种情况下可能会略有不同:
- 对象的 key/value 排序(对象 无序 )
- "Simple" 值
关于 "simple" 值,PHP documentation 是这样说的:
Like the reference JSON encoder, json_encode() will generate JSON that is a simple value (that is, neither an object nor an array) if given a string
, integer
, float
or boolean
as an input value
. While most decoders will accept these values as valid JSON, some may not, as the specification is ambiguous on this point.
To summarise, always test that your JSON decoder can handle the output you generate from json_encode().
如果您担心数据会被 100% 忠实地重新创建,请考虑在存储数据之前对其进行编码(即 base64_encode 它)。
P.S. 如果您要对数据进行 HMAC,则需要 1) 仅对值进行 HMAC 和 2) 确保始终访问这些值每次都以相同的顺序排列,因为 JSON 对除数组以外的任何内容都没有排序承诺。
我正在尝试使用 JavaScript(CryptoJS 库)和 PHP(内置 HMAC 函数)对字符串化数据进行 HMAC SHA256 哈希。我担心 JavaScript JSON.stringify 不会 consistent/identical 到 PHP json_encode() 函数。有没有更好的方法来对数据进行这种字符串化 (object/array)?
这是我的测试,有效。但是,我担心代码可能遇到的西班牙字符和其他 encodings/entities。
<h1>Testing HMAC Javascript to PHP Comparison</h1>
<br><br>
<div id="php_mac">
<?php
// Testing HMAC
$security_key = '0123456789';
$obj = array(
'field1' => 1,
'field2' => '2',
'field3' => "'",
);
// Calculate HMAC SHA256
$str_data = json_encode($obj);
echo "PHP str_data: ".$str_data."<br>";
$hash = hash_hmac('sha256', $str_data, $security_key, true);
$hashInBase64 = base64_encode($hash);
echo "PHP hashInBase64: ".$hashInBase64;
?>
</div>
<br><br>
<div id="javascipt_hmac">
<div id="javascript_str_data"></div>
<div id="javascript_hashInBase64"></div>
<script>
var security_key = '0123456789';
var obj = {
'field1': 1,
'field2': '2',
'field3': "'",
};
// Create security hash based on posted data
var str_data = JSON.stringify(obj);
$('#javascript_str_data').html('str_data: '+str_data);
// Using CryptoJS to HMAC SHA256 the str_data
var hash = CryptoJS.HmacSHA256(str_data, security_key);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
$('#javascript_hashInBase64').html('JS hashInBase64: '+hashInBase64)
</script>
</div>
其他想法:我担心 spacing/quoting 与 JSON 方法的差异。也许我应该循环遍历 object/array 并仅使用 "values" 来生成要进行 HMAC 处理的数据字符串?假设这可以保持为单个 array/object,那应该会产生一个一致的 "values" 字符串。但是,那么你如何保持一致的顺序。我假设它可以先按键订购。
正如@Pointy 在评论中提到的,JSON.stringify
和 json_encode
的输出在两种情况下可能会略有不同:
- 对象的 key/value 排序(对象 无序 )
- "Simple" 值
关于 "simple" 值,PHP documentation 是这样说的:
Like the reference JSON encoder, json_encode() will generate JSON that is a simple value (that is, neither an object nor an array) if given a
string
,integer
,float
orboolean
as an inputvalue
. While most decoders will accept these values as valid JSON, some may not, as the specification is ambiguous on this point.
To summarise, always test that your JSON decoder can handle the output you generate from json_encode().
如果您担心数据会被 100% 忠实地重新创建,请考虑在存储数据之前对其进行编码(即 base64_encode 它)。
P.S. 如果您要对数据进行 HMAC,则需要 1) 仅对值进行 HMAC 和 2) 确保始终访问这些值每次都以相同的顺序排列,因为 JSON 对除数组以外的任何内容都没有排序承诺。