Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signing JSON objects

Tags:

java

json

php

pki

I have to exchange JSON objects between different platforms and implementations of a service and make its integrity verifiable via digital signatures. So a platform A would create such an object and create a digital signature. Said signature is then included into the object and sent to platform B. The JSON objects can contain arbitrary attributes and data.

E.g. in PHP:

function signObject($jsonObjectToSign, $privateKey) {
    $jsonObjectToSign->signature = "";
    $msgToSign = json_encode($jsonObjectToSign);

    openssl_sign($msgToSign, $jsonObjectToSign->signature, $privateKey, OPENSSL_SLGO_SHA1);

    return $jsonObjectToSign;
}

Problem is, that e.g. in Java, there is no way to tell whether the attributes of a JSON object will be in the same order you added them (via JSONObject.put()). So, if I do a

$json = json_encode('{"a":1, "b":2}');

in PHP, sign this object as stated above, transfer it to a java based server, decode the json object and then try to verify the signature, I'd probably get a different order of the object's attributes.

So what I need, is a reliable way to create a String from a JSONObject, independent of the language or platform used.

The example object above needs always to output {"a":1, "b":2} and NEVER {"b":2, "a":1}. Unfortunately, this is the usual case e.g. in Java.

Is there any "best practice" to sign JSON Objects in a secure way?

But let me describe the problem in another way:

Let's say I want to do this in Java (or any other language):

JSONObject j = new JSONObject();
j.put("a", 1);
j.put("b", 2);

Now, I need a serialization function, that outputs always the same string representation for this object, no matter how and with what language this object is created.

like image 437
Xenonite Avatar asked Aug 03 '15 15:08

Xenonite


2 Answers

Signing and encryption of JSON objects is specified in the JOSE suite of specifications where JOSE stands for Javascript Object Signing and Encryption, see http://jose.readthedocs.org/en/latest/ JOSE uses a detached signature calculated over a base64url encode representation of the JSON object. The signature is not part of the JSON object itself so no re-ordering is required to validate it.

like image 82
Hans Z. Avatar answered Nov 15 '22 14:11

Hans Z.


As there is AFAIK no official (neither unofficial) standard on JSON Signing yet, I'd probably do a custom implementation. I'd define a new JSON object, e.g.

{
  "original": "..." // original JSON as a Base64 encoded string
  "signature": "..." // the signature
}

and implement a signing / signature verification layer on both/all sides of my system.

like image 24
Jozef Chocholacek Avatar answered Nov 15 '22 13:11

Jozef Chocholacek