我尝试使用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;串。但是,那么如何保持一致的排序。我认为它可以先用钥匙订购。
答案 0 :(得分:2)
正如@Pointy在评论中提到的,JSON.stringify
和json_encode
的输出在两种情况下可能略有不同:
在“简单”值上,PHP documentation可以这样说:
与引用JSON编码器一样,如果给定
string
,integer
,{{1},json_encode()将生成一个简单值的JSON(即,既不是对象也不是数组) }或float
作为输入boolean
。虽然大多数解码器都会接受这些值作为有效的JSON,但有些可能不会,因为规范在这一点上是模棱两可的 总而言之,请始终测试您的JSON解码器是否可以处理您从json_encode()生成的输出。
如果您担心数据被100%忠实地重新创建,请考虑在存储之前对数据进行编码(即base64_encode)。
PS 如果你要HMAC数据,你需要1)只有HMAC值和2)确保你每次都以相同的顺序访问值,因为JSON没有为数组以外的任何东西订购承诺。