Re: Proposal for key wrap/unwrap (ISSUE-35)

On Wed, Mar 6, 2013 at 11:15 AM, Mark Watson <watsonm@netflix.com> wrote:
>
> On Mar 6, 2013, at 10:46 AM, Richard Barnes wrote:
>
>>>>>
>>>>>     • Should the JWE object be passed to/from the UA in serialized form, or as a Javascript object ? In serialized form, it could be either the Compact Serialization or the JSON serialization. In object form, it would be a Javascript object that would JSON-serialize into the "JSON Serialization" of JWE
>>>>
>>>> I propose that we use the Compact Serialization.
>>>
>>> Any motivations for this?
>>>
>>> Within JOSE, the Compact Serialization is already shown to be divisive
>>> - and rightly so - in that it is not at all a JSON format. The notion
>>> of using dot-delimited encoding seems somewhat absurd/unnatural for a
>>> Javascript API.
>>
>> Big +1 to this.
>>
>>
>>>>>     • For wrapping with RSA-OAEP keys, JWE works by RSA-OAEP encrypting a symmetric Content Master Key which is then used to encrypt/integrity protect the payload. Where should we specify the encryption/integrity protection algorithm (likely A128CBC+HS256 or A128GCM) ? Possibly there should be an additional member in the parameters object used with generateKey when generating an RSA-OAEP wrapping key.
>>>>
>>>> We could capture the encryption/integrity algorithm in the algorithm name, so we would have RSA-OAEP+A128GCM-Wrap and RSA-OAEP+A128CBC+HS256-Wrap as separate WebCrypto algorithms.
>>>
>>> I don't understand the necessity of this. If we're going to specify
>>> the encryption/integrity protection algorithm, it should be part of
>>> the encoding, not part of the API. I do not think we should be adding
>>> JOSE algorithms like this - the JCE has shown how fundamentally flawed
>>> this construction is from an API perspective, I would like to avoid
>>> repeating those same mistakes.
>>
>> And you're not even going into the unnecessary crypto overhead.  The right thing to do here is to adjust JWK to support a wrapped key format, so that instead of using JWE over JWK, we would just use a wrapped JWK.  (This is a JOSE issue, to be discussed next week.)  That would resolve the question of identifiers, since you would just be using OAEP or AES key wrap directly.
>
> The issue here is that OAEP doesn't let you encrypt data or arbitrary size (the JWK object) without using keys of arbitrary size. If you want to wrap the JWK directly with an RSA key, then your options are RSA-KEM - which Ryan objected to - or using CMS to essentially do just what JWE does (OAEP encrypt a temporary symmetric key which is used to encrypt the payload and then pack the encrypted key and encrypted payload together into a CMS structure).

Sorry if my concerns raised on RSA-KEM were not clear. It was not
meant to be a strong objection - just a questioning of the design
rationale (which wasn't provided), given that 'native' support for
RSA-KEM is not in many APIs. It's certainly possible to roll your own
KEM (after all, it's just generating a random key and then wrapping
with RSA) - but as Mike's interop table suggested, there was concern
with that.

I don't anticipate any export issues with KEM that might otherwise
arise if we were talking about support for other new/arbitrary
algorithms, beyond possible FIPS considerations. But so far, we've
left that for implementations to work through.

>
>>
>>
>>>>>     • If the above parameter is added to the "RSA-OAEP wrapping" key type, how should it be encoded into JWK when such keys are exported ? (including when they themselves are wrapped)
>>>>
>>>> JWK can presently express that the key is an RSA-OAEP key to use used for key wrapping/unwrapping through the "alg" and "use" parameters. I propose we add the "enc" parameter to specify the associated encryption/integrity protection type.
>>>
>>> I'm not sure I follow this point.
>>
>> Doesn't seem like this is an issue if we use one-step (encrypt key) instead of two-step (encrypt CMK, then encrypt JWK) encryption.
>
> Sure.
>
>>
>>
>>>>>     • For wrapping with RSA-OAEP keys, JWE allows the public key to be included in the JWE header, to assist in identification of the private key needed to perform unwrapping (in the jwk member of the header). How should we specify during wrapping whether to include the public key ? (Note that if the answer to (1) is object form, then we could always include the public key and the script could just remove it before serialization if it wanted to).
>>>>
>>>> I don't have a good suggestion for this one.
>>>
>>> As you note, by not using the Compact Serialization, this should be
>>> available to the application, is it not?
>>
>> The reason this needs to be added by the API is that in JWE, the "jwk" attribute is covered by the integrity protection.  So the Javascript can't add it after the wrapping is done.
>
> Ah, ok. And so it can't remove it either.
>
>>
>> But again here, we should fix the problem with JWE and not try to hack around it here.
>>
>> --Richard
>>
>>
>>
>>>>>     • The compatibility and mapping between WebCrypto algorithm names and JOSE algorithm names needs to be defined (as it does for import/export as well)
>>>>>     • The mapping between the WebCrypto Key attribute "extractable" and a JWK equivalent needs to be defined
>>>>>     • The compatibility and mapping between WebCrypro Key attribute 'usages' and the JWK equivalent needs to be defined
>>>>
>>>> These should be straightforward.
>>>>
>>>>>
>>>>>
>>>>> …Mark
>>>>>
>>>>>
>>>>> On Mar 1, 2013, at 5:02 PM, Vijay Bharadwaj wrote:
>>>>>
>>>>>> Sounds like a reasonable approach.
>>>>>>
>>>>>> From: Mark Watson [mailto:watsonm@netflix.com]
>>>>>> Sent: Friday, March 1, 2013 4:36 PM
>>>>>> To: Vijay Bharadwaj
>>>>>> Cc: Ryan Sleevi; public-webcrypto@w3.org Group
>>>>>> Subject: Re: Proposal for key wrap/unwrap (ISSUE-35)
>>>>>>
>>>>>>
>>>>>> On Mar 1, 2013, at 9:53 AM, Vijay Bharadwaj wrote:
>>>>>>
>>>>>>
>>>>>> I've been looking at key wrap formats lately. My observations based on having maintained crypto APIs:
>>>>>>
>>>>>> 1. More wrapping formats means more confusion for developers and pain for vendors.
>>>>>> 2. Having wrapAlgorithm be a separate option on the import interface leads to various opportunities for inconsistency, since key wrapping formats include varying amounts of metadata. It is better to have import only deal with formats that are self-describing.
>>>>>>
>>>>>> So given that we generally look to JOSE for high-level formats, I'd like to propose using JWE encapsulation for the wrap/unwrap formats, and removing the wrapAlgorithm parameter (and perhaps keyAlgorithm, though this needs more thought) from createKeyImporter in Mark's proposal.
>>>>>>
>>>>>> A good starting point seems to be the JWE-protected JWK I-D at https://datatracker.ietf.org/doc/draft-miller-jose-jwe-protected-jwk/?include_text=1
>>>>>>
>>>>>> Three simple example usages of this format to illustrate what I expect will be the most common use cases:
>>>>>>
>>>>>> 1. For RSA wrapping: Proceed as in Section 5 of the above I-D. JWE header has alg set to RSA-OAEP, and jwk.kty set to RSA. Most people would likely use enc of A128CBC+HS256 or A128GCM.
>>>>>>
>>>>>> 2. For wrapping a key using AES: JWE header has alg set to dir, and enc as in #1. In this case the jwk element in the header is not necessary. This allows the use of any authenticated encryption mode, not just AES key wrap. This seems to be in line with the current consensus of the cryptographic community - NIST has also Approved the use of authenticated encryption modes for key wrapping: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
>>>>>>
>>>>>> 3. For working with existing legacy formats such as PKCS#8: JWE header has alg set to dir, and enc set to the appropriate value (e.g. "pkcs-8" in this case).
>>>>>>
>>>>>> IIUC, alg=dir means only that the symmetric Content Master Key (used to derive the Content Encryption Key for encrypting the JWE-payload) is pre-shared, rather than being encrypted and communicated in the JWE.
>>>>>>
>>>>>> The enc parameter stands for "encryption" not "encoding", so it's assumed in JWE that the content is always encoded (either with a CEK derived from a pre-shared CMK - alg=dir - or with a CEK derived from a CMK communicated in encrypted form in the JWE itself).
>>>>>>
>>>>>> So - at least based on my reading - it doesn't make sense to use JWE to carry unencrypted PKCS#8 format data for key import/export, though I guess you could specify enc = null - i.e. no encryption applied.
>>>>>>
>>>>>> The data type of the payload carried by the JWE can be specified in the "cty" (Content Type) member, which can be a MIME type, but usually you assume that the recipient is expecting a given data type. For our wrap/unwrap this would be implicitly a (serialization of) JWK, but I suppose we could use cty values to indicate that the payload is a PKCS#8 object etc. But this all feels rather messy.
>>>>>>
>>>>>> So, for the moment, I am leaning towards keeping import/export separate - with the import/export format indicated in a KeyFormat parameter. I'll update the proposal so that wrap/unwrap always expect a JWE: we will need to decide whether this is the Compact Serialization (passed as an ArrayBufferView) or the JSON Serialization (passed as an ArrayBufferView) or the JSON Serialization unserialized into a Javascript object (which could be defined in IDL as an explicit Dictionary Type that mirrors JWK-in-JWE).
>>>>>>
>>>>>> If, after we have fleshed out wrap/unwrap, we can see a clean way to make plain import/export sub-cases of that, then we can consolidate the operations into one pair of methods.
>>>>>>
>>>>>> Ryan makes a good point that translation between the different JWE serializations in Javascript is made ugly by the use of base64url (instead of plain base64). Another example of a simple data transformation function that is currently missing from the Web APIs. It would be nice to have zip as well...
>>>>>>
>>>>>> …Mark
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> The nice thing about this mechanism is that it's web-developer friendly, and adds minimal overhead for the case of the legacy formats.
>>>>>>
>>>>>> Thoughts? If people are okay with the general idea, I can work with Mark to revise the proposal as per our action item from the last meeting.
>>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Ryan Sleevi [mailto:sleevi@google.com]
>>>>>> Sent: Monday, February 25, 2013 1:51 PM
>>>>>> To: Mark Watson
>>>>>> Cc: public-webcrypto@w3.org Group
>>>>>> Subject: Re: Proposal for key wrap/unwrap (ISSUE-35)
>>>>>>
>>>>>> On Mon, Feb 25, 2013 at 1:18 PM, Mark Watson <watsonm@netflix.com> wrote:
>>>>>>
>>>>>>
>>>>>> ________________________________________
>>>>>> From: Ryan Sleevi [sleevi@google.com]
>>>>>> Sent: Wednesday, January 16, 2013 7:13 PM
>>>>>> To: Mark Watson
>>>>>> Cc: public-webcrypto@w3.org Group
>>>>>> Subject: Re: Proposal for key wrap/unwrap (ISSUE-35)
>>>>>>
>>>>>> Can you provide more design rationale for choosing RSA-KEM, rather
>>>>>> than the much more widely supported RSA-OAEP (eg: RFC 3560). I don't
>>>>>> know of a single well-tested, CORRECT implementation of RSA-KEM in the
>>>>>> popular cryptographic libraries and bindings.
>>>>>>
>>>>>> MW> Ryan, we looked in detail at RSA-OAEP key transport and there is an issue in that it does not support payloads of arbitrary size - as required for JWK format payloads. At least not without using RSA keys of arbitrary size.
>>>>>>
>>>>>> I'm not sure I follow. In the JOSE space, you perform an RSA-OAEP transport of the CMK, and the CMK protects the message. This is conceptually similar to RSA-KEM.
>>>>>>
>>>>>> Certainly, given that OAEP, but not KEM, is supported by JOSE, it seems more in line with your needs?
>>>>>>
>>>>>>
>>>>>>
>>>>>> Do you have any other suggestions for RSA-based key wrap/unwrap ?
>>>>>>
>>>>>> We also looked in detail at RSA-KEM and it doesn't look so bad after all. In fact it's much easier to understand than the RSA-OAEP documentation.
>>>>>>
>>>>>> ...Mark
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>>
>

Received on Wednesday, 6 March 2013 19:23:05 UTC