KeyWrap Proposal

From W3C Web Cryptography Wiki
Revision as of 01:46, 16 January 2013 by Mwatson2 (Talk | contribs)

Jump to: navigation, search

This is a proposal from Netflix for WebCrypto ISSUE 35 [1]

Use case

A Use Case for key wrapping is described in Video Service.

More generally, once a shared secret has been established between the client and a server in the form of a WebCrypto AES Key (for example through Diffie-Hellman or pre-provisioning), it is required to be able to deliver additional keys to the WebCrypto instance in possession of that secret, without exposing the raw keying material to the Javascript code.

This enables temporary session keys to be delivered for short-term use, whilst retaining the cryptographic link to the original shared secret rather than repeatedly using the original shared secret itself.

This has advantage where the browser implementation is trusted more than the Javascript code, since the raw key material is not exposed to Javascript.

Requirements

A "wrapped key" is a cryptographic key which has been encrypted or otherwise protected using another key, usually known as a Key Encryption Key (KEK). An example of an algorithm used to wrap keys is AES Key Wrap [2]. AES Key Wrap uses an AES Key to perform the wrapping. It does not specify the format of the key to be wrapped. Another example is RSA-KEM [4].

  1. The WebCrypto API should support a Key Wrapping operation. The Key Wrapping operation first formats the information associated with a Key object into a serializable form (as in the existing export operation) and then applies a Key Wrap Algorithm, using a Key Encryption Key (also represented as a Key object) to produce a wrapped key (in the form of an octet string).
  2. The WebCrypto API should support a Key Unwrapping operation. The Key Unwrapping operation takes a wrapped key, applies the inverse of a Key Wrap Algorithm, using a Key Encryption Key (also represented as a Key object) and then de-serializes the result (as in the existing import operation) to produce a new Key object
  3. The specified Key Wrap Algorithms should include AES Key Wrap [2] and RSA KEM [4].
  4. Key wrapping and unwrapping should support the same serialized key formats as the existing import and export operations
  5. For the JSON Web Key format [3], additional attributes may be included in the format as well as the raw key data. Mappings should be specified between attributes in the JWK structure to and from the type, algorithm, extractable and keyUsages attributes of the Key object.
  6. When unwrapping raw key data, it shall be possible for the user to specify the type, algorithm, extractable and keyUsages attributes of the Key object.
  7. When unwrapping JWK key data, the values of the type, algorithm, extractable and keyUsages attributes of the Key object shall be taken from the JWK structure. It shall be possible to specify defaults for the case where these attributes are not present in the JWK structure.
  8. If necessary, the WebCrypto specification shall define additional JKW structure members as necessary to achieve the above.
  9. Key Wrapping and Unwrapping shall be specified for at least the following kinds of key: AES keys, HMAC keys, ...

Proposal

Key interface (Section 11)

Add wrap and unwrap to KeyUsage enum:

enum KeyUsage {
  "encrypt",
  "decrypt",
  "sign",
  "verify",
  "wrap",
  "unwrap",
};

...

JSON Web Key

Add some material on JSON Web Key to Section 14:

Implementations SHOULD support additional JSON Web Key use values of:

  • wrap (key wrapping)

Implementations SHOULD support additional JSON Web Key members of:

  • extractable (boolean indicating extractability)

TODO: Register the above values with IANA

TODO: Specify key mapping and compatibility between JWK algorithm names with WebCrypto algorithm names.

Crypto interface (Section 18)

Add new wrapKey and unwrapKey methods to the Crypto interface:

KeyOperation unwrapKey( KeyFormat format,
                        ArrayBufferView key,
                        AlgorithmIdentifier? keyAlgorithm,
                        AlgorithmIdentifier? wrapAlgorithm,
                        Key keyEncryptionKey,
                        bool extractable = false,
                        KeyUsage[] keyUsages = [] );

KeyOperation wrapKey( KeyFormat format,
                      Key key,
                      AlgorithmIdentifier? wrapAlgorithm,
                      Key keyEncryptionKey );

The unwrapKey method

The unwrapKey method unwraps a key of the specified KeyFormat. It must act as follows:

  1. If keyAlgorithm is specified, let normalizedKeyAlgorithm be the result of processing keyAlgorithm according to the algorithm normalizing rules.
  2. If keyAlgorithm is specified and if normalizedKeyAlgorithm does not describe a registered algorithm throw a NotSupportedError and terminate the operation.
  3. If wrapAlgorithm is specified, let normalizedWrapAlgorithm be the result of processing wrapAlgorithm according to the algorithm normalizing rules.
  4. If wrapAlgorithm is specified and if normalizedWrapAlgorithm does not describe a registered algorithm throw a NotSupportedError and terminate the operation.
  5. Return a new KeyOperation object that will asynchronously return the result of performing the key unwrapping operation identified by normalizedWrapAlgorithm using keyEncryptionKey as the key wrapping key and interpreting the wrapped key as being of a type identified by normalizedKeyAlgorithm encoded in a format identified by keyFormat.

Wrapped keys SHALL be subject to the extraction and usage constraints of the key data, if any. The extractable argument SHALL NOT be honored if the key data does not allow extraction of the imported key. The imported key's usages SHALL consist of the intersection of the keyUsages argument and the usages specified in the key data of the imported key.

The keyAlgorithm may be null if the key algorithm is specified within the key data.

The wrapAlgorithm may be null if the key wrap algorithm is implicitly specified by the Key Encryption Key.

The wrapKey method

The keyEncryptionKey method encodes a key into the the specified KeyFormat and wraps it using the specified key wrapping algorithm and Key Encryption Key. It must act as follows:

  1. Let normalizedWrapAlgorithm be the result of processing wrapAlgorithm according to the algorithm normalizing rules.
  2. If normalizedWrapAlgorithm does not describe a registered algorithm throw a NotSupportedError and terminate the operation.
  3. Return a new KeyOperation object that will asynchronously return the result of performing the key wrapping operation identified by normalizedWrapAlgorithm using keyEncryptionKey as the Key Encryption Key applied to key formatted as specified by keyFormat.

RSAES-PKCS1-v1_5

Registration

The recognized algorithm name for this algorithm is "RSAES-PKCS1-v1_5".

Operation Parameters Result
encrypt None ArrayBufferView?
decrypt None ArrayBufferView?
generateKey RsaKeyGenParams KeyPair?
importKey None Key
exportKey None ArrayBufferView
unwrapKey None Key
wrapKey None ArrayBufferView

Operations

Unwrap Key

When unwrapping a key, the the resultant KeyOperation shall behave as follows:

  1. perform the unwrap operation defined for the wrapAlgorithm
  2. parse and extract the RSA key
  3. if either operation resulted in an error, raise an error and terminate the operation.
  4. Let result be a Key of the imported public or private key.
Wrap Key

When wrapping a key, the resulting KeyOperation shall behave as follows:

  1. Encode the RSA key into the format specified by keyFormat
  2. perform the wrap operation defined for the wrapAlgorithm
  3. if either operation resulted in an error, raise an error and terminate the operation.
  4. Let result be an ArrayBufferView of the wrapped public or private key.

... and similarly for other algorithms ...

AES Key Wrap

Description

The AES Key Wrap algorithm is described in RFC3394. This specification also requires the use of padding according to RFC5649 in order to support wrapped keys of arbitrary size.

Registration

The recognized algorithm name for this algorithm is "AES-KW".

Operation Parameters Result
generateKey AesKeyGenParams Key
importKey None Key
exportKey None ArrayBufferView
unwrapKey None Key
wrapKey None ArrayBufferView

Operations

Unwrap Key

NOTE: As with the the Unwrap Key section for other algorithms above this section describes the unwrapping of an AES Key Wrap Key i.e. the AES Key Wrap Key is the *wrapped* key, not the Key Encryption Key (there may of course be an AES Key Wrap Key used as Key Encryption Key if the wrapping operation is AES Key Wrap. Also note that, presently, the WebCrypto specification associates a key with a specific algorithm even though an AES Key can be used for any of AES Key Wrap, AES CTR, AES CBC - see https://www.w3.org/Bugs/Public/show_bug.cgi?id=20679

When unwrapping a key, the resulting KeyOperation shall behave as follows:

  1. perform the unwrap operation defined for the wrapAlgorithm
  2. parse and extract the AES Key Wrap key
  3. If the operation resulted in an error, queue a task to fire a simple event named onerror at the KeyOperation and terminate processing at this step
  4. Otherwise, let the result attribute of the KeyOperation be the unwrapped AES Key Wrap Key and queue a task to fire a simple event named oncomplete at the KeyOperation
Wrap Key

When wrapping a key, the resulting KeyOperation shall behave as follows:

  1. if the extractable attribute of the key has the value false, queue a task to fire a simple event named onerror at the KeyOperation and terminate processing at this step
  2. encode the AES Key Wrap key into the format identifier by keyFormat
  3. perform the wrap operation defined for the wrapAlgorithm
  4. if the operation resulted in an error, queue a task to fire a simple event named onerror at the KeyOperation and terminate processing at this step
  5. otherwise, let result be an ArrayBufferView of the wrapped AES Key Wrap key.

Algorithms

Unwrap

When unwrapping a wrapped key using AES Key Wrap, the following unwrapping steps shall be performed:

  1. Apply the RFC5649 unwrapping operation to the data provided in key, using keyEncryptionKey as the key encryption key
  2. If the result of the unwrapping operation is a failure of the data integrity check, raise an error and terminate the operation
  3. Otherwise, if the key data specifies a key algorithm
    1. if the keyAlgorithm parameter is null, set the key algorithm to be the key algorithm specified by the key data
    2. if the keyAlgorithm parameter is not null and the key algorithm specified by the key data is not compatible with the keyAlgorithm parameter, raise an error and terminate the operation.
    3. otherwise, set the key algorithm to be the key algorithm specified by the key data
  4. apply the key import operation for the key algorithm to output of the unwrap operation above, according to the requirements of the key algorithm
Wrap

When wrapping a key using AES Key Wrap, the following wrapping steps shall be performed:

  1. apply the key export operation for the key
  2. apply the RFC5649 wrapping operation to the output of the key export operation
  3. return the output of step 2

Examples

Wrapped key import

// The key type and exportability are specified in the JWK structure.
//
// keyJwk = { "kty":"oct",  "use" : "enc", "alg" : "A256", "exportable" : false,
//                  "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow",
//                  "kid":"bwVMkoqQ-EstJQLr_T-"}
//
// for the purposes of this example, wrappedKeyJwk = AESKeyWrap( UTF8( keyJwk ), keyEncryptionKey )

var unwrap = window.crypto.unwrapKey(  "jwk",
                  wrappedKeyJwk,
                  "AES-CTR",
                  "AES-KW",
                  wrappingKey,
                  true, // extractable
                  [ "encrypt" ] );
               
unwrap.oncomplete = function(event) {
  var key = event.target.result;
  console.log("Imported key type: " + key.type + "; algorithm " + key.algorithm.name + "; exportable " + key.exportable );
};

In the above example, the final output should indicate "exportable false", because the exportable attribute in the wrapped JWK structure is set to false."

[1] http://www.w3.org/2012/webcrypto/track/issues/35

[2] AES Key Wrap, RFC5649.

[3] JSON Private and Symmetric Key draft-jones-jose-json-private-and-symmetric-key.

[4] RSA Key Encapsulation Mechanism, RFC5990.