【问题标题】:General algorithm to securely serialize objects安全序列化对象的通用算法
【发布时间】:2015-03-18 14:18:23
【问题描述】:

我需要序列化一个(可能很复杂 *)对象,以便计算对象的MAC**。

如果您的消息是字符串,您可以简单地使用tag := MAC(key, string),如果s1 != s2 则很有可能是MAC(key, s1) != MAC(key, s2),而且在计算上很难找到s1,s2 这样MAC(k,s1) == MAC(k,s2)

现在我的问题是,如果您需要的不是字符串,而是 MAC 一个可以包含对象数组和嵌套对象的非常复杂的对象,会发生什么:

JSON
最初我虽然只使用 JSON 序列化可以解决问题,但事实证明 JSON 序列化程序并不关心顺序,例如:{b:2,a:1} 可以序列化为 {"b":2,"a":1}{"a":2,"b":1}

网址参数
您可以在对键进行排序后将对象转换为 url 查询参数列表,例如 {c:1,b:2} 可以序列化为 b=2&c=1。问题是随着对象变得越来越复杂,序列化变得难以理解。示例:{c:1, b:{d:2}}
1.首先我们序列化嵌套对象:{c:1, b:{d=2}} 2.然后url编码=符号:{c:1, b:{d%3D2}} 3.最终序列化为:b=d%3D2&c=1

如您所见,序列化很快变得不可读,虽然我还没有证明它,但我也觉得它不是很安全(即可以找到两条消息,MAC 具有相同的值)

谁能给我展示一个用于序列化对象的安全***算法?

[*]:对象可以有嵌套对象和嵌套对象数组。不允许循环引用。例子: {a:'a', b:'b', c:{d:{e:{f:[1,2,3,4,5]}}, g:[{h:'h'},{i:'i'}]}}

[**]: 这个MAC 然后将通过网络发送。我不知道服务器支持哪些语言/框架,因此无法使用特定于语言的解决方案,例如 Java 对象序列化。

[***]:在这种情况下安全意味着给定消息a,b:serialize(a) = serialize(b) 意味着a = b

编辑:我刚刚通过this 链接了解了SignedObject。是否存在与语言无关的等价物?

【问题讨论】:

  • 如果你想要一个独特的序列化来计算 MAC,你为什么要关心它的可读性是否好? (不,你不能从字符串中计算 MAC,只有当你也指定一个字符集时)
  • 而且,如果 MAC 算法对字符串工作正常且安全,为什么它不能对具有特定内容(JSON 等)的字符串工作?
  • @deviantfan 你是对的,可读性并不重要

标签: serialization cryptography


【解决方案1】:

您正在寻找的是规范表示,既可以用于数据存储本身,也可以用于应用 MAC 算法之前的预处理。一种广为人知的格式是用于 XML 签名的规范化。似乎 XML 签名的草案 2.0 版本也包括 HMAC。请注意,创建 XML 签名的安全验证充满危险 - 不要让自己被欺骗相信已签名的文档本身。

至于 JSON,似乎有一个规范的 JSON 草案,但我看不到它的状态或是否有任何兼容的实现。 Here 是出现相同问题的问答(用于散列而不是 MAC)。所以似乎没有一个完全标准化的方法。

在二进制中有 ASN.1 DER 编码,但您可能不想深入了解它,因为它非常复杂。


当然,您始终可以定义自己的二进制或文本表示,只要在语义上相同的数据集存在 一个 表示。在文本表示的情况下,您仍然需要定义特定的字符编码(推荐使用 UTF-8)来将表示转换为字节,因为 HMAC 只接受二进制输入。

【讨论】:

  • 感谢您的澄清。考虑到这一定是一个相当普遍的问题,没有“标准”的方法来做这件事似乎很奇怪。
  • 安迪:“标准的好处是你有很多选择。”
猜你喜欢
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多