安全序列化对象的通用算法
General algorithm to securely serialize objects
我需要序列化一个(可能很复杂 *)对象,以便我可以计算该对象的 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参数
您可以在对键进行排序后将对象转换为 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
将通过网络发送。我不知道服务器支持什么languages/frameworks,所以像Java对象序列化这样的特定语言解决方案是不可能的。
[***]:在此上下文中安全意味着给定消息 a
,b
:serialize(a) = serialize(b)
意味着 a = b
编辑:我刚刚通过this link 发现了SignedObject。是否有与语言无关的等价物?
您正在寻找的是 规范表示,或者用于数据存储本身,或者用于应用 MAC 算法之前的预处理。一种广为人知的格式是用于 XML 签名的规范化。 XML 签名的草案 2.0 版本似乎也包括 HMAC。请注意,创建 XML 签名的安全验证充满了危险 - 不要让自己受骗而相信已签名的文档本身。
至于 JSON,似乎有一个规范的 JSON 草案,但我看不到它的状态或是否有任何兼容的实现。 Here 是出现相同问题的 Q/A(用于散列而不是 MAC)。所以似乎没有完全标准化的方法。
在二进制中有 ASN.1 DER 编码,但您可能不想深入了解它,因为它非常复杂。
当然,您始终可以定义自己的二进制或文本表示,只要有一个 语义相同的数据集表示即可。在文本表示的情况下,您仍然需要定义特定的字符编码(建议使用 UTF-8)以将表示转换为字节,因为 HMAC 仅采用二进制输入。
我需要序列化一个(可能很复杂 *)对象,以便我可以计算该对象的 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参数
您可以在对键进行排序后将对象转换为 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
将通过网络发送。我不知道服务器支持什么languages/frameworks,所以像Java对象序列化这样的特定语言解决方案是不可能的。
[***]:在此上下文中安全意味着给定消息 a
,b
:serialize(a) = serialize(b)
意味着 a = b
编辑:我刚刚通过this link 发现了SignedObject。是否有与语言无关的等价物?
您正在寻找的是 规范表示,或者用于数据存储本身,或者用于应用 MAC 算法之前的预处理。一种广为人知的格式是用于 XML 签名的规范化。 XML 签名的草案 2.0 版本似乎也包括 HMAC。请注意,创建 XML 签名的安全验证充满了危险 - 不要让自己受骗而相信已签名的文档本身。
至于 JSON,似乎有一个规范的 JSON 草案,但我看不到它的状态或是否有任何兼容的实现。 Here 是出现相同问题的 Q/A(用于散列而不是 MAC)。所以似乎没有完全标准化的方法。
在二进制中有 ASN.1 DER 编码,但您可能不想深入了解它,因为它非常复杂。
当然,您始终可以定义自己的二进制或文本表示,只要有一个 语义相同的数据集表示即可。在文本表示的情况下,您仍然需要定义特定的字符编码(建议使用 UTF-8)以将表示转换为字节,因为 HMAC 仅采用二进制输入。