Является ли Javascript JSON.stringfy таким же, как json_encode PHP?

Я пытаюсь сделать HMAC SHA256 хеш-код строки данных, используя как JavaScript (CryptoJS Libraries), так и PHP (встроенная функция HMAC). Я обеспокоен тем, что 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? Предполагая, что это может быть сохранено в одном массиве / объекте, это должно привести к согласованной строке «значений». Но тогда как вы соблюдаете постоянный порядок. Я предполагаю, что это может быть заказано сначала ключом.

4

Решение

Как отметил @Pointy в комментариях, вывод JSON.stringify а также json_encode могут быть небольшие различия в двух сценариях:

  1. Порядок ключа / значения объекта (объекты неупорядоченный)
  2. «Простые» значения

На «простых» значениях PHP документация имеет это сказать:

Как и эталонный кодер JSON, json_encode () сгенерирует JSON, представляющее собой простое значение (то есть ни объект, ни массив), если ему string, integer, float или же boolean в качестве входа value, Хотя большинство декодеров примут эти значения как допустимые JSON, некоторые могут и не принять, поскольку в этом отношении спецификация неоднозначна.
Подводя итог, всегда проверяйте, может ли ваш JSON-декодер обрабатывать вывод, который вы генерируете из json_encode ().

Если вы беспокоитесь о том, что данные на 100% точно воссозданы, рассмотрите возможность кодирования данных перед их сохранением (то есть base64_encode).

Постскриптум Если вы собираетесь обрабатывать данные в HMAC, вам необходимо: 1) только значения HMAC и 2) убедиться, что вы всегда обращаетесь к значениям в одном и том же порядке каждый раз, потому что JSON не дает никаких обещаний упорядочения ни для чего, кроме массивов.

2

Другие решения

Других решений пока нет …