如何可靠地哈希JavaScript对象?
有没有一种可靠的方法来JSON.stringify一个JavaScript对象,保证所有的浏览器,node.js等ceated JSONstring是相同的,因为Javascript对象是相同的?
我想散列JS对象
{ signed_data: object_to_sign, signature: md5(JSON.stringify(object_to_sign) + secret_code) }
并通过Web应用程序(例如Python和node.js)和用户传递它们,以便用户可以针对一个服务进行身份validation,并显示该服务的下一个服务“签名数据”以检查数据是否可信。
但是,我发现JSON.stringify在实现中并不是唯一的:
- 在node.js / V8中,JSON.stringify返回一个没有不必要空白的JSONstring,比如'{“user_id”:3}。
- Python的simplejson.dumps留下一些空白,例如'{“user_id”:3}'
- 也许其他stringify实现可能会与空白,属性的顺序或任何其他方式不同。
有一个可靠的跨平台串化方法吗? 有没有“正规化的JSON”?
你会推荐其他的方法来散列这样的对象吗?
更新:
这是我用作解决方法:
normalised_json_data = JSON.stringify(object_to_sign) { signed_data: normalised_json_data, signature: md5(normalised_json_data + secret_code) }
所以在这个方法中,不是对象本身,而是它的JSON表示(这是特定于信号平台)被签名。 这很好,因为我现在签名是一个明确的string,我可以轻松JSON.parse数据后,我已经检查了签名散列。
这里的缺点是,如果我将整个{signed_data,signature}对象作为JSON发送,我必须调用JSON.parse两次,看起来并不好,因为内部的一个会被转义:
{"signature": "1c3763890298f5711c8b2ea4eb4c8833", "signed_data": "{\"user_id\":5}"}
你要求跨多种语言的实现是一样的……你几乎肯定不走运。 你有两个select:
- 检查www.json.org实施,看看他们是否可能更加标准化
- 在每种语言中使用自己的语言(使用json.org实现作为基础,而且应该做的工作很less)
您可能对npm包对象散列感兴趣,这似乎有一个相当好的活动和可靠性水平。
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
这是一个古老的问题,但我想我会添加一个当前的解决scheme,这个问题的任何谷歌推荐人。
现在签名和散列JSON对象的最好方法是使用JSON Web令牌 。 这允许对象签名,散列,然后根据签名进行validation。 它提供了一堆不同的技术,并有一个积极的发展组织。
您可以通过应用以下规则来规范化stringify()
的结果:
- 删除不必要的空白
- 在散列中sorting属性名称
- 明确的一致的引用风格
- 规范string内容(所以“\”和“A”变成一样)
这会给你留下一个标准的JSON表示,你可以可靠地哈希。