How to cryptographically hash a JSON object?

后端 未结 7 1705
醉话见心
醉话见心 2020-12-01 01:30

The following question is more complex than it may first seem.

Assume that I\'ve got an arbitrary JSON object, one that may contain any amount of data including oth

7条回答
  •  再見小時候
    2020-12-01 01:54

    This is the same issue as causes problems with S/MIME signatures and XML signatures. That is, there are multiple equivalent representations of the data to be signed.

    For example in JSON:

    {  "Name1": "Value1", "Name2": "Value2" }
    

    vs.

    {
        "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 could solve that problem, but it's a problem you don't need at all.

    The easy solution if you have control over the specification is to wrap the object in some sort of container to protect it from being transformed into an "equivalent" but different representation.

    I.e. avoid the problem by not signing the "logical" object but signing a particular serialized representation of it instead.

    For example, JSON Objects -> UTF-8 Text -> Bytes. Sign the bytes as bytes, then transmit them as bytes e.g. by base64 encoding. Since you are signing the bytes, differences like whitespace are part of what is signed.

    Instead of trying to do this:

    {  
       "JSONContent": {  "Name1": "Value1", "Name2": "Value2" },
       "Signature": "asdflkajsdrliuejadceaageaetge="
    }
    

    Just do this:

    {
       "Base64JSONContent": "eyAgIk5hbWUxIjogIlZhbHVlMSIsICJOYW1lMiI6ICJWYWx1ZTIiIH0s",
       "Signature": "asdflkajsdrliuejadceaageaetge="
    
    }
    

    I.e. don't sign the JSON, sign the bytes of the encoded JSON.

    Yes, it means the signature is no longer transparent.

提交回复
热议问题