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

时间:2016-02-02 14:58:44

标签: javascript php json cryptojs

我尝试使用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方法间隔/引用差异。也许我应该通过对象/数组循环并使用&#34;值&#34;只是为了生成HMAC的数据串?假设这可以保存到单个数组/对象,那么应该产生一致的&#34;值&#34;串。但是,那么如何保持一致的排序。我认为它可以先用钥匙订购。

1 个答案:

答案 0 :(得分:2)

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

  1. 对象的键/值排序(对象无序
  2. “简单”值
  3. 在“简单”值上,PHP documentation可以这样说:

      

    与引用JSON编码器一样,如果给定stringinteger,{{1},json_encode()将生成一个简单值的JSON(即,既不是对象也不是数组) }或float作为输入boolean。虽然大多数解码器都会接受这些值作为有效的JSON,但有些可能不会,因为规范在这一点上是模棱两可的   总而言之,请始终测试您的JSON解码器是否可以处理您从json_encode()生成的输出。

    如果您担心数据被100%忠实地重新创建,请考虑在存储之前对数据进行编码(即base64_encode)。

    PS 如果你要HMAC数据,你需要1)只有HMAC值和2)确保你每次都以相同的顺序访问值,因为JSON没有为数组以外的任何东西订购承诺。