Hi Richard, thanks for the example, some comments and questions: To clarify, in the JSON (non-compact) version, the payload is restricted to being a string? ie. it cannot be a JSON object? If so, that seems really limiting.
I don't understand why "cenc" needs to be added to the compact serialization. The recipient will need to know if it is in the compact format or in JSON before parsing. My gut tells me that signing the header is useful and will thwart some attacks -- but I am not an expert in that area. Is there some research that says it makes no difference? I think it would help catch implementation errors. -- Dick On Jul 2, 2013, at 3:20 PM, Richard Barnes <[email protected]> wrote: > Glad that helped. Detailed examples below. > > Couple of high-level points to help the examples make sense: > 1. Define a "cenc" header parameter, for "Content ENCoding", with one value, > "b64u". When present in the JSON serialization, the "payload" field is > base64url encoded; when it is absent, the "payload" field represents the > payload directly (as a UTF-8 string). > 2. For the compact serialization, "cenc" is always "b64u". > 3. When protected a header are present (always for the compact > serialization), the JWS Signing Input is base64(protected).base64(payload), > as it is in -11. When no protected header is present, the JWS Signing Input > is simply the octets of the payload. > > With that in mind, let's look at a few test cases. We'll use the following > inputs: > > Header: {"alg":"HS256","kid":"2"} > == 7b22616c67223a224853323536222c226b6964223a2232227d (hex UTF-8) > == eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ (base64 UTF-8) > > Key (kid=2): 0x0001020304050607 (8 octets) > > Payload: "café" > == 636166c3a9 (hex UTF-8) > == Y2Fmw6k (hex UTF-8) > > With those inputs, let's consider 4 cases that show the possibilities > discussed above. > > ### CASE 1: Compact / protected / b64u > > eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ > .Y2Fmw6k > .QUoMVpjxLXjH1ZAX9tw4QEPnL6G_Hvd4EjD-JsHilyk > > No change here. The compact case just represents the special case where the > payload is base64-encoded and all the headers are protected. Thus, we use > the base64.base64 form for the JSON Signing Input. > JWS Signing Input: eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ.Y2Fmw6k (as a UTF-8 > string) > == > 65794a68624763694f694a49557a49314e694973496d74705a434936496a496966512e5932466d77366b > (hex) > > ### CASE 2: JSON / protected / b64u > > { > "unprotected":{"cenc":"b64u"}, > "protected":"eyJhbGciOiJIUzI1NiIsImtpZCI6IjIifQ", > "payload":"Y2Fmw6k", > "signature":"QUoMVpjxLXjH1ZAX9tw4QEPnL6G_Hvd4EjD-JsHilyk" > } > > This is just the JSON equivalent to Case 1. > > ### CASE 3: JSON / unprotected / b64u > > { > "unprotected":{"alg":"HS256","kid":"2","cenc":"b64u"}, > "payload":"Y2Fmw6k", > "signature":"X-GwEVfz9WEi0UhrmK1muKXecqxMipngSL_ZenXw5Lo" > } > > Here we've removed the integrity protection from the headers (because who > needs it? ;) ). So the signature is different, because JWS Signing Input > here is just the payload. > JWS Signing Input: café (as a UTF-8 string) > == 636166c3a9 (hex) > > ### CASE 4: JSON / unprotected / plain > > { > "unprotected":{"alg":"HS256","kid":"2"}, > "payload":"café", > "signature":"X-GwEVfz9WEi0UhrmK1muKXecqxMipngSL_ZenXw5Lo" > } > > This object is equivalent to Case 3, but with the payload expressed directly > as a JSON string instead of base64-encoded. And, if you ask me, the > prettiest and most human-readable of the whole menagerie here :) > > I've written a script to generate these test cases, in case you want to play > with this some more: > <http://test.polycrypt.net/temp/hello-jose.html> > > Hope this helps, > --Richard > > > On Fri, Jun 28, 2013 at 7:04 PM, Dick Hardt <[email protected]> wrote: > Hi Richard, that helps. > > Our you looking at a way of effectively signing a JSON payload? A complete, > real world example would help alot. > > > On Fri, Jun 28, 2013 at 3:57 PM, Richard Barnes <[email protected]> wrote: > Hey Dick, > > I guess I should have been clearer that I was only talking about the JSON > serialization. My proposed change would have no impact on the compact > serialization. Hopefully that answers your questions about separators, etc.; > they payload would just be a normal JSON string. > > --Richard > > > On Thu, Jun 27, 2013 at 7:56 PM, Dick Hardt <[email protected]> wrote: > > > > On Thu, Jun 27, 2013 at 3:24 PM, Richard Barnes <[email protected]> wrote: > I think there are two separable issues here, both of which Mike and I > probably have divergent opinions on :) > 1. Syntax: Should it be possible for the "payload" field JWS to be a JSON > string (instead of base64) when the payload is simply a UTF-8 string? > > One of the goals of the token was that it not require encoding for it to be > transported in a request. IE that it be safe and SIMPLE to include in an HTTP > header or in a URL > > 2. Crypto: Must the JWS Signing Input be base64url encoded. > > The current answers to these questions are: > 1. It is not possible. Payload is always base64url encoded. > 2. It is always base64url encoded. > > The answers should be: > 1. The payload should not be base64url encoded unless it cannot be > represented as a JSON string. > > How does an implementation determine which parts are separated? Are '.' > escaped? Does the implementation need to parse the JSON to determine a valid > separator? How does it know the end of the JSON? That sounds really hard to > implement, or I am misunderstanding what you are proposing. > > > 2. The JWS Signing Input should not be base64url encoded unless there is a > JWS Protected Header > > Neither of these are complicated changes: > 1. Add a "b64" header parameter that indicates that the payload is > base64url-encoded binary, as opposed to a UTF-8 string. Specify that this > parameter is on by default in compact-formatted JWS objects. > > And how is the header separated from the payload? > > 2. Modify the signing/verification instructions to switch based on the > presence of a JWS Protected Header: "If the JWS Protected Header is absent or > empty, then the JWS Signing Input is simply the JWS Payload (not encoded). > If the JWS Protected Header has a non-empty value, then the the JWS Signing > Input is the concatenation of the Encoded JWS Header, a period ('.') > character, and the Encoded JWS Payload" > > There are two reasons for these, both of which are important to make sure > that this spec is applicable to a broad variety of use cases: > 1. Compactness. As Jim notes, quoted strings are shorter than > base64url-encoded strings > > The tokens are already compact enough. > > 2. Crypto-compatibility: Avoiding base64-encoding means that there's nothing > JWS-specific about the signature value. So for example, you could translate > a JWS with no protected attributes to a CMS SignedData object with no > protected attributes. > > Not a useful feature from my point of view. > > -- Dick > > > > _______________________________________________ > jose mailing list > [email protected] > https://www.ietf.org/mailman/listinfo/jose > > > _______________________________________________ > jose mailing list > [email protected] > https://www.ietf.org/mailman/listinfo/jose
_______________________________________________ jose mailing list [email protected] https://www.ietf.org/mailman/listinfo/jose
