我需要序列化一个(可能很复杂的 *)对象,以便我可以计算对象的MAC
**。
如果您的消息是字符串,那么您可以tag := MAC(key, string)
,s1 != s2
然后MAC(key, s1) != MAC(key, s2)
的概率非常高,而且计算上很难找到s1,s2
,MAC(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对象序列化等语言特定的解决方案。
[***]:此上下文中的安全意味着给定的消息a
,b
:serialize(a) = serialize(b)
意味着a = b
编辑:我刚刚通过this链接找到了SignedObject。是否存在与语言无关的等同物?
答案 0 :(得分:0)
您正在寻找的是规范表示,无论是数据存储本身,还是应用MAC算法之前的预处理。一种相当已知的格式是用于XML签名的规范化。看起来草案2.0版的XML签名也包括HMAC。请注意,创建XML签名的安全验证充满了危险 - 不要让自己被欺骗信任签名文档本身。
至于JSON,似乎有一个规范的JSON草案,但我看不到它的状态或是否有任何兼容的实现。 Here是Q / A,其中出现相同的问题(对于散列而不是MAC)。所以似乎没有一种完全标准化的方法。
在二进制文件中有ASN.1 DER编码,但你可能不想进入它,因为它非常复杂。
当然,只要存在语义相同的数据集的一个表示,您就可以随时定义自己的二进制或文本表示。在文本表示的情况下,您仍然需要定义特定的字符编码(建议使用UTF-8)将表示转换为字节,因为HMAC仅采用二进制输入。