On Fri, Jan 23, 2015 at 4:14 PM, Mike Jones <[email protected]> wrote:
> As I wrote earlier (and as pointed out by James Manger as the format was > being designed), the array serialization is subject to collisions between > keys of different types unless the field names are also included. [e, kty, > n] in theory could match [kty, x, y] for a different key type, and yet not > be the same key. So the representation needs to include the field names or > equivalent metadata – not just the field values. > This seems like a total red herring. You can solve this entirely by putting kty in a fixed position (first). As for being brittle and dealing with escaping, at least the printf for a > particular key type can take advantage of knowledge about the > representation of that key type. For instance, for RSA, EC, and OCT keys, > no escaping will ever be needed since the values are all ASCII strings, so > the code can be simple. > > > I agree that any hash input computation with the right properties would do > the job. Those properties are primarily the ability to unambiguously > represent a JWK key and necessary key metadata as an octet sequence. Yes, > we could choose anything. But the good news about the choice in the > current draft, which was James Manger’s idea, is that we already have a > data structure that is known to be able to unambiguously represent JWK > keys, both existing ones and future ones, as an octet sequence. That data > structure is a JWK itself! That’s why I know that the other inventors and > I were drawn to James’ suggestion and why I personally think that it gives > us the right balance of simplicity now and flexibility in the future. > If we had a canonical form for JSON, or even canonicalizing serializers, I would agree with you. But we don't, so I don't. --Richard > > > Best > wishes, > > -- Mike > > > > *From:* Richard Barnes [mailto:[email protected]] > *Sent:* Friday, January 23, 2015 12:19 PM > > *To:* Mike Jones > *Cc:* John Bradley; Matt Miller; Jim Schaad; [email protected] > *Subject:* Re: [jose] Working Group last call on > draft-ietf-jose-jwk-thumbprint > > > > > > > > On Fri, Jan 23, 2015 at 2:02 PM, Mike Jones <[email protected]> > wrote: > > In practice, you wouldn’t ever implement the sort. You’d have printf > statements for the key types you support (and we’ve only defined three of > them to date – only two if you only use public keys). So in pseudo-code, > the hash input generator I would write would look something like this: > > > > if kty == “RSA” then > > printf(‘{“e”:”’, e, ‘”,”kty”:”’, kty, ‘”,”n”:”’, n, ‘”}’) > > else if kty == “EC” then > > printf(‘{“crv”:”’, crv, ‘”,”kty”:”’, kty, ‘”,”x”:”’, x, ‘”,”y”:”’, y, > ‘”}’) > > else > > FAIL > > > > No sorting code involved! > > > > You may notice that I put something similar in my first message on this > thread :) > > > > My point is that this style of code is brittle and deals poorly with > things like escaping. > > > > I can see your point w.r.t. separators. That seems to indicate that > Matt's suggestion of a JSON array is the right answer: > > > > tp_input = JSON.stringify([jwk.e, jwk.kty, jwk.n]).replace(/\s/g, "") > > > > That way the order is preserved, but the JSON serializer handles all the > string serialization. > > > > --Richard > > > > > > > > *From:* Richard Barnes [mailto:[email protected]] > *Sent:* Friday, January 23, 2015 10:54 AM > *To:* Mike Jones > *Cc:* John Bradley; Matt Miller; Jim Schaad; [email protected] > > > *Subject:* Re: [jose] Working Group last call on > draft-ietf-jose-jwk-thumbprint > > > > > > > > On Fri, Jan 23, 2015 at 1:39 PM, Mike Jones <[email protected]> > wrote: > > I was about to write a similar message to John's. James Manger also > pointed out the need to have different hash inputs for different kinds of > keys, so as to avoid the possibility of collisions. The simple suggestion > earlier in the thread of using an array of values for the hash input > doesn't have this property. If there were two kinds of keys with the same > number of values in the input, for instance three values such as [A, B, C], > then without also having the member tags "kty", etc. in the hash input, > collisions are possible. > > That's why James suggested that the natural and safe hash input for a JWK > is a sorted JWK itself. We went with that. > > > > The problem is that there's no good way to create a "sorted JWK". (BTW, > you also mean "whitespace-free".) Thankfully, the whitespace problem is > easy to deal with here. Since the included attributes do not allow any > internal whitespace, you can just delete all whitespace. But sorting is a > big deal. Like I said, it basically requires you to hand-serialize the > JSON. At which point, you might as well use ASN.1 :) > > > > ISTM that (1) including "kty" and (2) using a delimiter that's not in the > allowed character set would together address the collision issues. So we > could get away with something like "kty-value|n-value|e-value". Miller's > proposal to use a JSON array would also work for me, although it would > require removing white space in case the serializer added any. Anything > that doesn't require custom serialization code :) > > > > > > > > > > I agree that encodings using ASN.1 sort of defeat the point. Others could > define how to do that and add them to the appropriate registries if they > want, but using JSON solutions is the point of the working group and this > draft. > > As for symmetric keys, I don't think we actually have a use case for them > at present. I'd be fine with the working group deciding to drop them or to > add security considerations on the necessity for there to be sufficient key > entropy if a thumbprint is to be exposed to a party not holding the key. > Or the security considerations could say that the thumbprint MUST only be > exposed to parties already in possession of the key. While I understand > going the salt route, I'm only comfortable with us doing that now if > someone has a real use case for it. Since I think the chairs want to have > this draft complete quickly, I'd rather drop symmetric keys than figure out > the salt mechanisms on the fly. But others are free to propose otherwise, > obviously. > > At a meta-point responding to Jim's message, I think this morning's > discussions exactly demonstrate the value of the draft being in the working > group. There's a lot of good discussion going on about the choices made, > tradeoffs, and alternatives that wouldn't necessarily happen if this > weren't a working group draft. > > Thanks all, > -- Mike > > -----Original Message----- > From: jose [mailto:[email protected]] On Behalf Of John Bradley > Sent: Friday, January 23, 2015 10:18 AM > To: Matt Miller > Cc: Richard Barnes; Jim Schaad; [email protected] > Subject: Re: [jose] Working Group last call on > draft-ietf-jose-jwk-thumbprint > > Mat in the first version that we did, we didn't have delimiters. > > I think it was James Manger that pointed out that without delimiters there > were some potential attacks. > > Depending on the order of the parameters the issues are different. > > I think the specific issue was concatenating e directly to n. > > That lead us to create the current doc. > > John B. > > > > On Jan 23, 2015, at 2:28 PM, ⌘ Matt Miller <[email protected]> wrote: > > > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA512 > > > > On 1/23/15 7:54 AM, Richard Barnes wrote: > >> I would summarize my reaction to this document as "I can live with > >> it, but it makes me really sad that we didn't do the stupid simple > >> obvious thing." > >> > >> The computation of the hash input is technically workable, but > >> unnecessarily complex. Rather than building a simple string based on > >> the components (say, ), it basically requires the implementor to make > >> a custom JSON serializer to ensure that the fields are serialized in > >> the right order. > >> > >> Using Javascript as an example, instead of just doing a simple string > >> construction: > >> > >> tp_input = [jwk.e, jwk.kty, jwk.n].join("|") > >> > >> ... instead, I construct and fill in a template: > >> > >> tp_input = '{"e":"JWK_E","kty":"JWK_KTY","n":"JWK_N"}' > >> .replace("JWK_E", jwk.e) .replace("JWK_KTY", jwk.kty) > >> .replace("JWK_N", jwk.n) > >> > >> Requiring a lot of manual coding like this seems to invite interop > >> issues. > >> > >> The remainder of the text looks fine to me, though. > >> > > > > I agree with Richard that the hash input looks needlessly complex. > > Picking a delimiter isn't necessary if it instead takes advantage of > > existing JSON implementations by simply serializing an array of the > > required values, still ordered lexicographically according to their > > associated member names. > > > > In some real code, that's: > > > > * JavaScript: tp_input = JSON.stringify([jwk.e, jwk.kty, jwk.n]); > > * Ruby: tp_input = JSON.generate [ jwk["e"], jwk["kty"], jwk["n"] ] > > * Python: tp_input = json.dumps([jwk['e'], jwk['kty'], jwk['n']) > > > > This could very well get rid of most of section 5. It might also get > > rid of some of text in Section 7 regarding weird member names if we're > > careful. > > > > > > - -- > > - - m&m > > > > Matt Miller < [email protected] > > > Cisco Systems, Inc. > > -----BEGIN PGP SIGNATURE----- > > Version: GnuPG/MacGPG2 v2.0.22 (Darwin) > > Comment: GPGTools - https://gpgtools.org > > > > iQEcBAEBCgAGBQJUwoTDAAoJEDWi+S0W7cO16gYH+wbQ+RhWRoPOXDEXa0ieyqzD > > GxS+6Jj77QQjknkm9bfw+6mTzP0+CFshy4OJP/qNQScRLSTvDS20sQUPPb4/NAbq > > CV/xV9Td/OrT/73iwR17PHoovLkwHOhbgxX93U4XA6JXVXSlslM0hUKBsDfmqM4j > > jBI0yRvowAweDhmQ5rqdHhH4WBQQamR2XT8y61H9ERHAvlru3v5C9n3Qwa9Y8/ju > > 1SjzQc1t1UIE3vOmhkxZWlkDfnWI6grOoGDt/JIy7JIK/0WJ/g8mjbqUTh61xU3V > > a6SAjw0fjvhfJQ6FJfmmteOYVCOeUO0fCNTCjnkDBMtz9Zho+H7WUfXBvE5QrrY= > > =lZoe > > -----END PGP SIGNATURE----- > > > > _______________________________________________ > > jose mailing list > > [email protected] > > https://www.ietf.org/mailman/listinfo/jose > > > > >
_______________________________________________ jose mailing list [email protected] https://www.ietf.org/mailman/listinfo/jose
