如何可靠地哈希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表示,你可以可靠地哈希。