Как надежно хэш-объекты 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}"}
Ответы
Ответ 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 вашего объекта, которое вы можете тогда надежно хешировать.