安全序列化对象的通用算法

时间:2015-03-18 14:18:23

标签: serialization cryptography

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

如果您的消息是字符串,那么您可以tag := MAC(key, string)s1 != s2然后MAC(key, s1) != MAC(key, s2)的概率非常高,而且计算上很难找到s1,s2MAC(k,s1) == MAC(k,s2) {1}}。

现在我的问题是,如果不是字符串,你需要做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对象序列化等语言特定的解决方案。

[***]:此上下文中的安全意味着给定的消息abserialize(a) = serialize(b)意味着a = b

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

1 个答案:

答案 0 :(得分:0)

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

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

在二进制文件中有ASN.1 DER编码,但你可能不想进入它,因为它非常复杂。


当然,只要存在语义相同的数据集的一个表示,您就可以随时定义自己的二进制或文本表示。在文本表示的情况下,您仍然需要定义特定的字符编码(建议使用UTF-8)将表示转换为字节,因为HMAC仅采用二进制输入。