I'm trying to do an HMAC SHA256 hash of stringified data using both JavaScript (CryptoJS Libraries) and PHP (built in HMAC function). I'm concerned that the JavaScript JSON.stringify will not be consistent/identical to the PHP json_encode() function. Is there a better approach to this stringifying of the data (object/array)?
Here's my test, which works. But, I'm concerned about Spanish characters and other encodings/entities that the code may encounter.
<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>
Additional thoughts: I'm worried about spacing/quoting differences with JSON methods. Perhaps I should loop thru the object/array and use the "values" only to produce the string of data to be HMAC'ed? Assuming this can be kept to a single array/object, that should produce a consistent "values" string. But, then how do you keep a consistent ordering. I assume it could be ordered by key first.