jjw*_*ign 5 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>
Run Code Online (Sandbox Code Playgroud)
其他想法:我担心与 JSON 方法的间距/引用差异。也许我应该遍历对象/数组并仅使用“值”来生成要进行 HMAC 处理的数据字符串?假设这可以保留在单个数组/对象中,那应该会产生一致的“值”字符串。但是,那么你如何保持一致的排序。我认为它可以先按钥匙订购。
正如@Pointy在评论中提到的,JSON.stringify和的输出json_encode在两种情况下可能略有不同:
关于“简单”值,PHP 文档是这样说的:
与参考 JSON 编码器一样,如果给定
string、或作为输入,json_encode() 将生成简单值 JSON(即既不是对象也不是数组)。虽然大多数解码器会接受这些值作为有效的 JSON,但有些解码器可能不会,因为规范在这一点上不明确。 总而言之,请始终测试您的 JSON 解码器是否可以处理从 json_encode() 生成的输出。integerfloatbooleanvalue
如果您担心数据是否 100% 忠实地重新创建,请考虑在存储数据之前对其进行编码(即对其进行 base64 编码)。
PS如果您要对数据进行 HMAC,则需要 1)仅对值进行 HMAC 并 2)确保每次始终以相同的顺序访问值,因为 JSON 对除数组之外的任何内容都没有排序承诺。