Javascript的JSON.stringfy和PHP的json_encode一样吗?

我正在尝试使用JavaScript(CryptoJS库)和PHP(内置HMAC功能)对字符串化数据进行HMAC SHA256哈希.我担心JavaScript JSON.stringify与PHP json_encode()函数不一致/相同.有没有更好的方法来对数据(对象/数组)进行字符串化?

这是我的测试,有效.但是,我担心代码可能会遇到的西班牙语字符和其他编码/实体.

<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>

其他想法:我担心使用JSON方法间隔/引用差异.也许我应该通过对象/数组循环并仅使用“值”来生成要进行HMAC的数据字符串?假设这可以保存到单个数组/对象,那么应该产生一致的“值”字符串.但是,那么如何保持一致的排序.我假设它可以先按键排序.

解决方法:

正如@Pointy在评论中提到的,JSON.stringify和json_encode的输出在两种情况下可能略有不同:

>对象的键/值排序(对象是无序的)
>“简单”的价值观

关于“简单”的价值观,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).

附:如果你要HMAC数据,你需要1)只有HMAC值和2)确保你每次都以相同的顺序访问值,因为JSON没有为除数组之外的任何东西做出订单承诺.

上一篇:javascript – Crypto.js:IE 11中未定义“Uint8ClampedArray”


下一篇:javascript – CryptoJS使用密码加密AES,但PHP解密需要密钥