jsonb-api icon indicating copy to clipboard operation
jsonb-api copied to clipboard

ES6 Compatible Parsing & Serialization

Open jsonbrobot opened this issue 7 years ago • 11 comments

ES6 (EcmaScript version 6) and forward specifies very specific rules for serialization including "predictive property" order. This may appear strange but for a human creating the properties A, B, C and getting them serialized as A, C, B is slightly awkward, although completely compatible with JSON.

In addition, ES6 also specifies strict rules for serializing numbers which are quite different from what native Java does.

Anyway, a huge advantage with ES6 parsing and serialization is that it makes it possible creating very elegant "crypto safe" objects as described here: https://cyberphone.github.io/doc/security/jsonsignatures.html

This is currently supported by an open source library of mine (https://github.com/cyberphone/openkeystore#openkeystore) but it would be even cooler if ES6 compatible parsing and serialization would be a part of JSON-B or at least of your reference implementation. This should be coordinated with your JavaScript engine since the very same scheme must be running there already.

jsonbrobot avatar Jun 09 '17 14:06 jsonbrobot

  • Issue Imported From: https://github.com/javaee/jsonb-spec/issues/50
  • Original Issue Raised By:@cyberphone
  • Original Issue Assigned To: Unassigned

jsonbrobot avatar May 23 '18 22:05 jsonbrobot

@rmannibucau Commented Default is the lexicographic order. However you can use https://github.com/javaee/jsonb-spec/blob/master/api/src/main/java/javax/json/bind/annotation/JsonbPropertyOrder.java to fit your need.

jsonbrobot avatar May 16 '18 06:05 jsonbrobot

@cyberphone Commented This issue is actually a bit flawed (dated) because ES6 compatible JSON serialization consists of two entirely different things:

  • Serialization of JSON primitives (Numbers, Literals, and Strings)
  • Property ordering (which also affects parsing)

https://tools.ietf.org/id/draft-erdtman-jose-cleartext-jws-00.html depends on both features.

Predictive property ordering a la ES6 requires something like: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html. Is that achievable through the various Java/JSON APIs? Bear with me, I'm unarguable NOT an expert on those.

JSON Number serialization is an awkward chapter, not even JDK's JavaScript engine (Nashorn) follows the ECMAScript standard. MSFT is currently working on getting their counterpart ES6 compatible.

jsonbrobot avatar May 16 '18 07:05 jsonbrobot

@rmannibucau Commented Hmm, parsing is not (and must not actually to respect the mapping side of the spec) affected at jsonp or jsonb level since it is a bean matching which is done so we are all good.

Ordering is deterministic and predictable as mentionned in previous mail and should in any case be enforced by the user if needed with the related API (order annotation).

The primitive serialization is handled by json-p accoring to json spec.

jsonbrobot avatar May 16 '18 07:05 jsonbrobot

@cyberphone Commented For enveloped clear text signatures based on ES6 rules, parsing and serialization are closely intertwined. In retrospect I've noted that this complicates the implementation in many JSON APIs, which is why I nowadays rather advocate for using traditional canonicalization, like in XML DSig but way simpler: https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html

It would be interesting hearing your opinion on this matter because a draft is just a draft :-)

jsonbrobot avatar May 16 '18 07:05 jsonbrobot

@rmannibucau Commented I strongly think we can't change the defaults since they really match today's way of working. However JSON-P (I don't think JSON-B is affected) can get a flag you pass to the generator factory to normalize the data. Would make sense. Then JSON-B would just passtrough the flag.

jsonbrobot avatar May 16 '18 08:05 jsonbrobot

@cyberphone Commented

I strongly think we can't change the defaults since they really match today's way of working

For my poor understanding only: Does this mean that the Java APIs in question by default are unable parsing JSON Numbers or JSON Strings produced by Browsers and Node.js?

jsonbrobot avatar May 16 '18 09:05 jsonbrobot

@rmannibucau Commented No, it works well. It just means that normalizing everything is not good since current representation - which is stable/deterministic - is already in used and what is used and mainstream.

jsonbrobot avatar May 16 '18 10:05 jsonbrobot

@cyberphone Commented That was what I expected. This also means that if the serialization API (JSON-P?) would be enhanced with ES6 compliant serialization of Strings and Numbers (for ints, floats and doubles only NB) as default, nothing would/should change/break with respect to the User Community. Such code is readily available.

The remaining hurdle (property ordering), would in your case already be fixed (-minus some minor spec work) if the IETF signature scheme in the workings, would be revised to rather depend of lexicographic than on predictive ordering.

Well, there is this I-JSON thing as well, but as shown by the following Twitter message

{"id": 10765432100123456789, "id_str": "10765432100123456789", ...}

the industry have already found "solutions" 😂

jsonbrobot avatar May 16 '18 12:05 jsonbrobot

@cyberphone Commented Oops! I just found a (for the mentioned application only) breaking issue:

4.2 Customizing Property Order To customize the order of serialized properties only for one specific type, JSON Binding provides javax.json.bind.annotation.JsonbPropertyOrder annotation. Order specified by JsonbPropertyOrder annotation overrides order specified by PropertyOrderStrategy

Here is the "problem": https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html#json.wireformat

jsonbrobot avatar May 16 '18 12:05 jsonbrobot

@cyberphone Commented After chatting with @rmannibucau on IRC it became clear that changing default serialization of numbers to match ES6 is unrealistic since there are systems out there relying on JSON-P's specific formatting.

That effectively leaves us (me) with a single option: Add an item CANONICALIZED to the PropertyOrderStrategy set which implies the following:

  • Unconditionally serialize properties in LEXICOGRAPHIC order
  • Use ES6 compatible Number and String formatting

jsonbrobot avatar May 16 '18 15:05 jsonbrobot