Warning:
This wiki has been archived and is now read-only.
KeyWrap Proposal
Contents
This proposal is not up-to-date
See https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html, https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796 and https://www.w3.org/Bugs/Public/show_bug.cgi?id=23885
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, if a client and server have a shared AES key (for example through Diffie-Hellman or pre-provisioning), or the private and public parts of an RSA key (respectively), it is required to be able to deliver additional keys to the WebCrypto instance in possession of the shared or private 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 secret rather than repeatedly using the original 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].
- 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).
- 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
- Key wrapping and unwrapping should support the same serialized key formats as the existing import and export operations
- 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.
- 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.
- 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.
- If necessary, the WebCrypto specification shall define additional JKW structure members as necessary to achieve the above.
- Key Wrapping and Unwrapping shall be specified for at least the following kinds of key: AES keys, HMAC keys, ...
Proposal
Overview and Open Issues
We propose that key wrapping in the WebCrypto API be supported through the use of JWE-protected JWK objects [5] [6]. We propose specific algorithms for wrapping with AES keys and with RSA-OAEP keys.
The following issues require discussion with the Working Group:
- 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
- PROPOSAL: tbd - both JSON Serialization and the JS object are described below
- 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.
- PROPOSAL: Additional optional parameter to wrapKey. For example an enum, JweMethod, with values A128CBC+HS256 and A128GCM
- 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)
- PROPOSAL: Not applicable given proposal for above issue
- 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).
- PROPOSAL: Mandate inclusion of the public key
- 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
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
Mapping between JOSE Algorithm names, specifically the JWK kty
and optional alg
fields and WebCrypto algorithms names is defined in the table below:
kty
|
alg
|
WebCrypto algorithm |
---|---|---|
RSA
|
RSA1_5
|
RSAES-PKCS1-v1_5 |
RSA
|
RS256 , RS384 , RS512
|
RSASSA-PKCS1-v1_5 |
RSA
|
? | RSA-PSS |
RSA
|
RSA-OAEP
|
RSA-OAEP |
EC
|
ES256 , ES384 , ES512
|
ECDSA |
oct
|
A128CBC , A256CBC
|
AES-CBC |
oct
|
A128CTR , A256CTR
|
AES-CTR |
oct
|
A128KW , A256KW
|
AES-KeyWrap |
oct
|
A128GCM , A256GCM
|
AES-GCM |
oct
|
? | HMAC |
Note: the mapping above assumed that alg
values defined for JWE and JWS can also be used in JWK.
The following table specifies mapping from WebCrypto KeyUsage values and the JWK use
member:
KeyUsage
|
use
|
---|---|
encrypt
|
enc
|
decrypt
|
enc
|
sign
|
sig
|
verify
|
sig
|
wrap
|
wrap
|
unwrap
|
wrap
|
Note: JWK does not provide the capability to distinguish between an operation and its inverse (or between sign and verify). When mapping from JWK uses to WebCrypto KeyUsages, both WebCrypto KeyUsages associated with the JOSE use are allowed.
Crypto interface (Section 18)
Add new wrapKey
and unwrapKey
methods to the Crypto
interface:
enum JweMethod { “A128CBC+HS256”, “A128GCM” }; KeyOperation unwrapKey( ArrayBufferView wrappedKey, AlgorithmIdentifier? keyAlgorithm, Key keyEncryptionKey, bool extractable = false, KeyUsage[] keyUsages = [] ); KeyOperation wrapKey( Key key, Key keyEncryptionKey, AlgorithmIdentifier? keyEncryptionAlgorithm, JweMethod? enc ); /* If a JS object form is used for the wrapped key, then the wrappedKey parameter of unwrapKey * (and the result returned in the KeyOperation returned from wrapKey) becomes a Jwe dictionary * defined below */ dictionary JweHeader { DOMString header; // Encoded JWE Header DOMString encrypted_key; // Encoded JWE Encrypted Key DOMString integrity_value; // Encoded JWE Integrity Value }; dictionary Jwe { JweHeader[] recipients; DOMString initialization_vector; // Encoded JWE Initialization Vector DOMString ciphertext; // Encoded JWE Ciphertext };
The unwrapKey method
The unwrapKey
method unwraps a key provided as a UTF-8 encoded, JSON serialized JWE-protected JWK object. It must act as follows:
- If
keyAlgorithm
is specified, let normalizedKeyAlgorithm be the result of processingkeyAlgorithm
according to the algorithm normalizing rules. - If
keyAlgorithm
is specified and if normalizedKeyAlgorithm does not describe a registered algorithm throw aNotSupportedError
and terminate the operation. - Return a new
KeyOperation
object that will asynchronously return the result of performing the key unwrapping operation usingkeyEncryptionKey
as the key encryption key and, ifkeyAlgorithm
was specified, interpreting the wrapped key as being of a type identified by normalizedKeyAlgorithm. Note that the wrapped key may include information about the key algorithm, which must be compatible with normalizedKeyAlgorithm.
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 unwrapped 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 wrapKey method
The wrapKey
method encodes a key into a (UTF-8 encoded, JSON serialized|Javascript object containing a) JWE-protected JWK object. It must act as follows:
- Return a new
KeyOperation
object that will asynchronously return the result of performing the key wrapping operation usingkeyEncryptionKey
as the Key Encryption Key applied tokey
.
AES Key Wrap
Description
This algorithm wraps/unwraps a key of any type to/from a JWE-protected JWK object using AES Key Wrap.
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 or Jwe (tbd)
|
Operations
Unwrap Key
When unwrapping a wrapped key using AES Key Wrap, the following unwrapping steps shall be performed:
- Deserialize the serialized JWE object provided in the
wrappedKey
parameter to theunwrapKey
operation - If the
alg
member of the JWE is notA128KW
or theenc
member is notA128CBC+HS256
orA128GCM
then raise an error and terminate the operation - Unwrap the Content Master Key using the
keyEncryptionKey
and the AES Key Wrap algorithm - Decrypt and integrity check the JWE payload using the Content Master Key as described in JWE
- If the result of the unwrapping operation is a failure of the data integrity check, raise an error and terminate the operation
- Otherwise, interpret the JWE payload as a UTF-8 encoded JSON serialized JWK object
- If the JWK key data specifies a key algorithm
- if the
keyAlgorithm
parameter to theunwrapKey
operation is null, set the key algorithm to be the key algorithm specified by the key data - if the
keyAlgorithm
parameter to theunwrapKey
operation is not null and the key algorithm specified by the key data is not compatible with thekeyAlgorithm
parameter, raise an error and terminate the operation. - otherwise, set the key algorithm to be the intersection of the key algorithm specified by the JWK key data and the key algorithm specified in the
keyAlgorithm
parameter to theunwrapKey
- if the
- apply the key import operation for the key algorithm to the output of the unwrap operation above, according to the requirements of the key algorithm
Wrap Key
When wrapping a key using AES Key Wrap, the following wrapping steps shall be performed:
- apply the key export operation for the key to obtain a JWK object
- serialize the JWK object to UTF-8 encoded JSON
- generate a Content Master Key and use this to apply encryption and integrity protection to the serialized JWK object, as described in JWE, using the protection method specified by the
enc
parameter, if provided and otherwise using AES GCM - apply the AES Key Wrap algorithm to the Content Master Key using the
keyEncryptionKey
. Thealg
member of the JWE object SHALL beA128KW
and theenc
member SHALL beA128GCM
orA128CBC+HS256
. - serialize the resulting JWE object using the JSON serialization and UTF-8 encoding
- return the output of step 2
RSA-OAEP Wrapping
Description
This algorithm wraps/unwraps a key of any type to/from a JWE-protected JWK object using RSA-OAEP encryption.
Registration
The recognized algorithm name for this algorithm is "RSA-OAEP".
Operation | Parameters | Result |
---|---|---|
generateKey | RsaKeyGenParams |
Key
|
importKey | None | Key
|
exportKey | None | ArrayBufferView
|
unwrapKey | None | Key
|
wrapKey | None | ArrayBufferView
|
NOTE: The inclusion of unwrapKey and wrapKey operations here, and in the description below, refers to the operations unwrap and wrap being performed on keys of this type, *not* to the use of keys of this type as Key Encryption Keys. The algorithms section below describes the use of an RSA key as Key Encryption Key.
Operations
Unwrap
When unwrapping a wrapped key using RSA-OAEP Wrapping, the following unwrapping steps shall be performed:
- Deserialize the serialized JWE object provided in the
wrappedKey
parameter to theunwrapKey
operation - If the
alg
member of the JWE is notRSA-OAEP
, raise an error and terminate the operation - Decrypt the encapsulated JWK object using
keyEncryptionKey
as the Content Master Key for the JWE object. - If the result of the unwrapping operation is a failure of the data integrity check, raise an error and terminate the operation
- Otherwise, if the JWK key data specifies a key algorithm
- if the
keyAlgorithm
parameter to theunwrapKey
operation is null, set the key algorithm to be the key algorithm specified by the key data - if the
keyAlgorithm
parameter to theunwrapKey
operation is not null and the key algorithm specified by the key data is not compatible with thekeyAlgorithm
parameter, raise an error and terminate the operation. - otherwise, set the key algorithm to be the key algorithm specified by the JWK key data
- if the
- 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 RSA-OAEP Wrapping, the following wrapping steps shall be performed:
- apply the key export operation for the key to obtain a JWK object
- encrypt the serialized JWK object into a JWE object using the
keyEncryptionKey
as the Content Master Key. Thealg
member of the JWE object SHALL beRSA-OAEP
. - serialize the resulting JWE object using the Compact Serialization
- 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", "extractable" : false, // "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow", // "kid":"bwVMkoqQ-EstJQLr_T-"} // // for the purposes of this example, wrappedKeyJwk = JWE( UTF8( keyJwk ), keyEncryptionKey ) var unwrap = window.crypto.unwrapKey( wrappedKeyJwk, "AES-CTR", wrappingKey, true, // extractable [ "encrypt" ] ); unwrap.oncomplete = function(event) { var key = event.target.result; console.log("Imported key type: " + key.type + "; algorithm " + key.algorithm.name + "; extractable " + key.extractable ); };
In the above example, the final output should indicate "extractable false", because the extractable 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.
[5] Using JavaScript Object Notation (JSON) Web Encryption (JWE) for Protecting JSON Web Key (JWK) Objects draft-miller-jose-jwe-protected-jwk
[6] JSON Web Key (JWK) draft-ietf-jose-json-web-key