Подтвердить что ты не робот

Как надежно хэш-объекты JavaScript?

Есть ли надежный способ для JSON.stringify объекта JavaScript, который гарантирует, что конечная строка JSON одинакова во всех браузерах, node.js и т.д., учитывая, что объект Javascript тот же?

Я хочу хэш-объекты JS, такие как

{
  signed_data: object_to_sign,
  signature:   md5(JSON.stringify(object_to_sign) + secret_code)
}

и передавать их через веб-приложения (например, Python и node.js) и пользователя, чтобы пользователь мог аутентифицироваться в отношении одной службы и показывать следующую службу "подписанные данные" для этого, чтобы проверить, являются ли данные подлинный.

Однако я столкнулся с проблемой, что JSON.stringify не уникален для всех реализаций:

  • В node.js/V8 JSON.stringify возвращает строку JSON без лишних пробелов, например '{ "user_id": 3}.
  • Python simplejson.dumps оставляет некоторые пробелы, например. '{ "user_id": 3}'
  • Вероятно, другие реализационные реализации могут иметь дело иначе с пробелами, порядком атрибутов и т.д.

Есть ли надежный кросс-платформенный метод стягивания? Есть ли "номинированный JSON"?

Не могли бы вы порекомендовать другие способы хэш-объектов вроде этого?

UPDATE:

Это то, что я использую в качестве обходного пути:

normalised_json_data = JSON.stringify(object_to_sign)
{
  signed_data: normalised_json_data,
  signature:   md5(normalised_json_data + secret_code)
}

Таким образом, в этом подходе подписывается не сам объект, а его JSON-представление (которое является специфическим для платформы sigining). Это хорошо работает, потому что то, что я подписываю сейчас, является однозначной строкой, и я могу легко JSON.parse данные после того, как я проверил хэш-подпись.

Недостаток здесь заключается в том, что если я отправлю весь объект {signed_data, signature} как JSON, я должен дважды вызвать JSON.parse, и он выглядит не так хорошо, потому что внутренняя сторона получает escape-код:

{"signature": "1c3763890298f5711c8b2ea4eb4c8833", "signed_data": "{\"user_id\":5}"}
4b9b3361

Ответ 1

Вы просите, чтобы реализация чего-то на нескольких языках была одинаковой... вам почти не повезло. У вас есть два варианта:

  • проверить реализации www.json.org, чтобы узнать, могут ли они быть более стандартизированными.
  • сворачивайте свой собственный язык на каждом языке (используйте json.org-реализации в качестве базы, и там должно быть очень мало работы)

Ответ 2

Вам может быть интересен пакет npm object-hash, который, похоже, обладает довольно хорошей активностью и надежностью уровень.

var hash = require('object-hash');

var testobj1 = {a: 1, b: 2};
var testobj2 = {b: 2, a: 1};
var testobj3 = {b: 2, a: "1"};

console.log(hash(testobj1)); // 214e9967a58b9eb94f4348d001233ab1b8b67a17
console.log(hash(testobj2)); // 214e9967a58b9eb94f4348d001233ab1b8b67a17
console.log(hash(testobj3)); // 4a575d3a96675c37ddcebabd8a1fea40bc19e862

Ответ 3

Это старый вопрос, но я думал, что добавлю текущее решение этого вопроса для любых рефери Google.

Лучший способ подписи и хэш-объектов JSON теперь - использовать JSON Web Tokens. Это позволяет подписывать объект, хешировать, а затем проверять другими на основе подписи. Он предлагает множество различных технологий и имеет активную группу разработчиков.

Ответ 4

Вы можете нормализовать результат stringify(), применяя такие правила, как:

  • удалить лишние пробелы.
  • имена атрибутов сортировки в хэшах
  • четко определенный стиль цитирования
  • нормализовать содержимое строки (так что "\ u0041" и "A" станут прежними)

Это оставит вас с каноническим представлением JSON вашего объекта, которое вы можете тогда надежно хешировать.