一尘不染

如何对JSON对象进行密码哈希处理?

json

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

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

最后一部分是要求,因为JSON将由许多不同平台上的各种(反)序列化器生成/读取。我知道至少有一个Java
JSON库,该库在反序列化期间读取数据时会完全删除格式。这样,它将破坏哈希。

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

最后,也不希望将整个JSON字符串散列为字节块(反序列化之前),因为JSON中的某些字段在计算散列时应忽略。

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


阅读 273

收藏
2020-07-27

共1个答案

一尘不染

当为允许灵活性的任何数据格式计算散列时,该问题是一个常见问题。要解决此问题,您需要 规范化 表示形式。

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

XML DSIG以相同的方式工作-
在对XML进行签名之前,需要对其进行规范化。有一个提议的W3标准涵盖此内容,因为它是签名的基本要求。有人称它为c14n。

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

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

  • 按名称从大到小对属性进行排序
  • 所有名称上使用双引号
  • 在所有字符串值上使用双引号
  • 名称和冒号之间以及冒号和值之间没有空格或一个空格
  • 值和以下逗号之间没有空格
  • 所有其他空白都折叠为一个空格或一无所有-选择一个
  • 排除您不想签名的任何属性(一个示例是保存签名本身的属性)
  • 使用您选择的算法对结果进行签名

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

规范化表示不必是您在应用程序中传递的表示。只要给定任意JSON对象,就可以轻松生成它。

2020-07-27