如何加密散列 JSON 对象? [英] How to cryptographically hash a JSON object?

查看:27
本文介绍了如何加密散列 JSON 对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下问题比最初看起来要复杂.

The following question is more complex than it may first seem.

假设我有一个任意 JSON 对象,它可能包含任意数量的数据,包括其他嵌套的 JSON 对象.我想要的是 JSON 数据的加密哈希/摘要,而不考虑实际的 JSON 格式本身(例如:忽略 JSON 令牌之间的换行符和间距差异).

Assume that I've got an arbitrary JSON object, one that may contain any amount of data including other nested JSON objects. What I want is a cryptographic hash/digest of the JSON data, without regard to the actual JSON formatting itself (eg: ignoring newlines and spacing differences between the JSON tokens).

最后一部分是一项要求,因为 JSON 将由许多不同平台上的各种(反)序列化程序生成/读取.我知道至少有一个用于 Java 的 JSON 库可以在反序列化期间读取数据时完全删除格式.因此它会破坏散列.

The last part is a requirement, as the JSON will be generated/read by a variety of (de)serializers on a number of different platforms. I know of at least one JSON library for Java that completely removes formatting when reading data during deserialization. As such it will break the hash.

上面的任意数据子句也使事情变得复杂,因为它阻止我以给定的顺序获取已知字段并在拥有之前将它们连接起来(大致想想 Java 的非加密 hashCode() 方法是如何工作的).

The arbitrary data clause above also complicates things, as it prevents me from taking known fields in a given order and concatenating them prior to hasing (think roughly how Java's non-cryptographic hashCode() method works).

最后,将整个 JSON 字符串作为一个字节块(在反序列化之前)散列也是不可取的,因为在计算散列时应该忽略 JSON 中的某些字段.

Lastly, hashing the entire JSON String as a chunk of bytes (prior to deserialization) is not desirable either, since there are fields in the JSON that should be ignored when computing the hash.

我不确定这个问题是否有好的解决方案,但我欢迎任何方法或想法 =)

I'm not sure there is a good solution to this problem, but I welcome any approaches or thoughts =)

推荐答案

在为任何允许灵活性的数据格式计算哈希时,这个问题很常见.为了解决这个问题,您需要规范化表示.

The problem is a common one when computing hashes for any data format where flexibility is allowed. To solve this, you need to canonicalize the representation.

例如,Twitter 和其他服务用于身份验证的 OAuth1.0a 协议需要请求消息的安全哈希.要计算散列,OAuth1.0a 说您需要首先按字母顺序排列字段,用换行符分隔它们,删除字段名称(众所周知),并为空值使用空行.签名或散列是根据该规范化的结果计算的.

For example, the OAuth1.0a protocol, which is used by Twitter and other services for authentication, requires a secure hash of the request message. To compute the hash, OAuth1.0a says you need to first alphabetize the fields, separate them by newlines, remove the field names (which are well known), and use blank lines for empty values. The signature or hash is computed on the result of that canonicalization.

XML DSIG 的工作方式相同 - 您需要在签署 XML 之前对其进行规范化.有一个提议的 W3 标准涵盖了这一点,因为它是签署.有些人称之为c14n.

XML DSIG works the same way - you need to canonicalize the XML before signing it. There is a proposed W3 standard covering this, because it's such a fundamental requirement for signing. Some people call it c14n.

我不知道 json 的规范化标准.值得研究.

I don't know of a canonicalization standard for json. It's worth researching.

如果没有,您当然可以为您的特定应用程序使用建立一个约定.一个合理的开始可能是:

If there isn't one, you can certainly establish a convention for your particular application usage. A reasonable start might be:

  • 按名称按字典顺序对属性进行排序
  • 所有名称都使用双引号
  • 所有字符串值都使用双引号
  • 名称和冒号之间以及冒号和值之间没有空格或一个空格
  • 值和以下逗号之间没有空格
  • 所有其他空白都折叠成一个空格或什么都没有 - 选择一个
  • 排除您不想签名的任何属性(例如,拥有签名本身的属性)
  • 使用您选择的算法对结果进行签名

您可能还想考虑如何在 JSON 对象中传递该签名 - 可能建立一个众所周知的属性名称,如nichols-hmac"或其他东西,它会获取 base64 编码版本的哈希.散列算法必须明确排除此属性.然后,JSON 的任何接收者都可以检查散列.

You may also want to think about how to pass that signature in the JSON object - possibly establish a well-known property name, like "nichols-hmac" or something, that gets the base64 encoded version of the hash. This property would have to be explicitly excluded by the hashing algorithm. Then, any receiver of the JSON would be able to check the hash.

规范化的表示不必是您在应用程序中传递的表示.它只需要在给定任意 JSON 对象的情况下轻松生成.

The canonicalized representation does not need to be the representation you pass around in the application. It only needs to be easily produced given an arbitrary JSON object.

这篇关于如何加密散列 JSON 对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆