这与S/MIME签名和XML签名存在的问题相同。也就是说,要签名的数据有多个等效的表示方式。
例如,在JSON中:
{ "Name1": "Value1", "Name2": "Value2" }
对比。
{
"Name1": "Value\u0031",
"Name2": "Value\u0032"
}
或者,根据您的应用程序,这甚至可能是等效的:
{
"Name1": "Value\u0031",
"Name2": "Value\u0032",
"Optional": null
}
规范化可以解决这个问题,但实际上你根本不需要面对这个问题。
如果您能够控制规范,简单的解决方法是将对象包装在某种容器中,以保护它免于转换为"等效"但不同的表示形式。
也就是说,不要签署"逻辑"对象,而是签署特定的序列化表示形式。例如,JSON对象--> UTF-8文本-->字节。将字节视为字节进行签名,然后通过base64编码将其传输为字节。由于您正在签署字节,因此像空格之类的差异是签署的一部分。
不要尝试这样做:
{
"JSONContent": { "Name1": "Value1", "Name2": "Value2" },
"Signature": "asdflkajsdrliuejadceaageaetge="
}
只需执行以下操作:
{
"Base64JSONContent": "eyAgIk5hbWUxIjogIlZhbHVlMSIsICJOYW1lMiI6ICJWYWx1ZTIiIH0s",
"Signature": "asdflkajsdrliuejadceaageaetge="
}
不要对JSON进行签名,而是签名编码后的JSON字节。是的,这意味着签名不再透明。