This is the same issue as problems with S / MIME signatures and XML signatures. That is, there are several equivalent representations of the data that must be signed.
For example, in JSON:
{ "Name1": "Value1", "Name2": "Value2" }
against.
{ "Name1": "Value\u0031", "Name2": "Value\u0032" }
Or depending on your application, this may even be equivalent:
{ "Name1": "Value\u0031", "Name2": "Value\u0032", "Optional": null }
Canonicalization may solve this problem, but it is a problem that you do not need at all.
A simple solution, if you have control over the specification, is to wrap the object in some kind of container to protect it from being converted to an "equivalent" but different representation.
those. avoid the problem by not signing a βlogicalβ object, but instead by signing a specific serialized view.
For example, JSON β UTF-8 Text β Bytes objects. Sign the bytes as bytes , then pass them as bytes , for example. base64 encoded. Since you are signing bytes, differences, such as whitespace, are part of the signature.
Instead of this:
{ "JSONContent": { "Name1": "Value1", "Name2": "Value2" }, "Signature": "asdflkajsdrliuejadceaageaetge=" }
Just do the following:
{ "Base64JSONContent": "eyAgIk5hbWUxIjogIlZhbHVlMSIsICJOYW1lMiI6ICJWYWx1ZTIiIH0s", "Signature": "asdflkajsdrliuejadceaageaetge=" }
those. do not sign JSON, sign bytes of encoded JSON.
Yes, this means that the signature is no longer transparent.