- From: Mark Watson <watsonm@netflix.com>
- Date: Thu, 17 Jan 2013 04:52:27 +0000
- To: Ryan Sleevi <sleevi@google.com>
- CC: "public-webcrypto@w3.org Group" <public-webcrypto@w3.org>
On Jan 16, 2013, at 7:13 PM, Ryan Sleevi wrote: > 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. For our application we need to wrap a key using a private key and unwrap using the corresponding public key. No strong opinions on the exact algorithm. If RSA-OAEP is more widely supported, let's specify that instead. > > Your extension of RSAES-PKCS1-v1_5 is not at all correct, considering > that RSA-KEM has nothing to do with RSAES (eg: it is intentionally > structure-less). You've misunderstood the proposal. For each algorithm, X, we have sections for import-X and export-X which deal with importing and exporting an "X Key". Similarly, what I added to RSAES-PKCS1-v1_5 was "unwrap-X" and "wrap-X" which deal with unwrapping and wrapping an X key, where X= RSAES-PKCS1-v1_5. These sections are independent of the key wrapping algorithm and type of key encryption key used. I'm not saying I like this format and I would agree if you said it was confusing, but that's the way the spec is right now. I'm well aware that RSAES-PKCS1-v1_5 is a different thing from RSA-KEM. > We're talking about an entirely different algorithm > here, orthogonal from RSASSA and RSAES, and distinct from RSA-PSS and > RSA-OAEP. Yes, I added a section for an actual key wrapping algorithm (AES Key Wrap) below. We would need a separate section for RSA-KEM as well if we choose to specify it. > > Further, the parameters necessary in order to specify RSA-KEM are huge > (see Section B.4 for a more visual example of all the details > necessary to be specified) You are convincing me, at least, on this point… ...Mark > > On Tue, Jan 15, 2013 at 4:37 PM, Mark Watson <watsonm@netflix.com> wrote: >> All, >> >> I have updated our proposal for this issue and posted it here: >> http://www.w3.org/2012/webcrypto/wiki/KeyWrap_Proposal >> >> Regards, >> >> Mark >> >> On Oct 30, 2012, at 1:38 AM, Mark Watson wrote: >> >> All, >> >> Here is a proposal in response to ISSUE-35 [1], using JWK (with extensions) >> as the format for the key and associated parameters before wrapping. >> Wrapping and unwrapping are considered aspects of key export and import >> (respectively). To export/import without wrapping the user just specifies >> the wrap algorithm as null. >> >> 1) Add "wrap" and "unwrap" to KeyUsage enum: >> >> "10. Key interface >> >> enum KeyUsage { >> "encrypt", >> "decrypt", >> "sign", >> "verify", >> "wrap", >> "unwrap", >> };" >> >> 2) Add wrapped attribute to KeyImporter and KeyExporter. Specify the >> character encoding of JSON Web Keys (we assume that all key export >> operations result in an ArrayBufferView): >> >> "15. KeyImporter interface >> >> enum KeyFormat { >> // An unformatted sequence of bytes. Intended for secret keys. >> "raw", >> // The BER encoding of the RSAPublicKey structure from RFC 3447. >> // Only usable with RSA keys. >> "pkcs1-public", >> // The BER encoding of the RSAPrivateKey structure from RFC 3447. >> // Only usable with RSA keys. >> "pkcs1-private", >> // The BER encoding of the PrivateKeyInfo structure from RFC 5208. >> "pkcs8", >> // The key is represented as UTF-8 encoded JSON according to the JSON Web >> Key format. >> "jwk" >> }; >> >> interface KeyImporter : KeyOperation { >> void import(); >> >> readonly attribute KeyFormat format; >> readonly attribute boolean wrapped; >> }; >> >> interface KeyExporter : KeyOperation { >> void export(); >> >> readonly attribute KeyFormat format; >> readonly attribute boolean wrapped; >> }; >> >> 15.1. JSON Web Key >> >> 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) >> • startdate (key start date in seconds since the epoch) >> • enddate (key end date in seconds since the epoch) >> Implementations SHOULD expose additional JSON Web Key members as attributes >> contained within the extra attribute of the Key objects. >> >> TODO: Specify encoding of key attributes of potentially arbitrary type into >> extra attribute map >> TODO: Specify JWK formats for private and symmetric keys >> TODO: Register the above values with IANA >> TODO: Specify key compatibility between JWK algorithm names with WebCrypto >> algorithm names." >> >> 3) Modify createKeyImporter and createKeyExporter to take optional wrapping >> algorithm and key >> >> "18. Crypto interface >> >> KeyImporter createKeyImporter( KeyFormat format, >> ArrayBufferView key, >> AlgorithmIdentifier? keyAlgorithm, >> AlgorithmIdentifier? wrapAlgorithm, >> Key? wrappingKey, >> bool temporary = true, >> bool extractable = false, >> KeyUsage[] keyUsages = [] ); >> >> KeyExporter createKeyExporter( KeyFormat format, >> Key key, >> AlgorithmIdentifier? wrapAlgorithm, >> Key? wrappingKey ); >> >> "18.1.8 The createKeyImporter method >> >> The createKeyImporter method returns a new KeyImporter object that will >> import >> new keys of the, potentially wrapped, 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 KeyImporter object S with the following characteristics: >> 1. S.result = null >> 2. S.format = format >> 3. S.wrapped = true if wrapAlgorithm is not null, false otherwise >> >> Imported keys SHALL be subject to the extraction and usage constraints of >> the key >> data, if any. The temporary argument SHALL be honored. 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. >> >> 18.1.9 The createKeyExporter method >> >> The createKeyExporter method returns a new KeyExporter object that will >> export >> existing keys in the specified KeyFormat. It must act as follows: >> >> 1. If the key does not exist throw a KeyNotFoundError and terminate the >> operation. >> 2. If wrapAlgorithm is specified, let normalizedWrapAlgorithm be the >> result of processing wrapAlgorithm according to >> the algorithm normalizing rules. >> 3. If wrapAlgorithm is specified and if normalizedWrapAlgorithm does not >> describe a registered algorithm throw a >> NotSupportedError and terminate the operation. >> 4. If wrapAlgorithm is specified and wrappingKey is null, or if >> wrapAlgorithm is null and wrappingKey is specified, throw a >> NotSupportedError and terminate the operation >> 4. If the wrappingKey is not null and does not exist throw a >> KeyNotFoundError >> and terminate the operation. >> 5. Return a new KeyExporter object S with the following characteristics: >> 1. S.result = null >> 2. S.format = format >> 3. S.wrapped = true if wrapAlgorithm is not null, false otherwise" >> >> 4) Add text on import/export for RSAES-PKCS1-v1_5 keys >> >> "24.3. RSAES-PKCS1-v1_5 >> >> 24.3.2. 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? >> >> 24.3.4 Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the RSA key into the format >> 2. If the key is to be wrapped, 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 exported public or private >> key." >> >> 5) Add text on import/export for RSASSA-PKCS1-v1_5 keys >> >> "24.4. RSASSA-PKCS1-v1_5 >> >> 24.4.2. Registration >> >> The recognized algorithm name for this algorithm is "RSASSA-PKCS1-v1_5". >> >> Operation | Parameters | Result >> ================================================ >> sign | RsaSsaParams | ArrayBufferView? >> verify | RsaSsaParams | boolean? >> generateKey | RsaKeyGenParams | KeyPair? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.4.4. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the RSA key into the format >> 2. If the key is to be wrapped, perform the wrap operation defined for >> the wrapAlgorithm >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be an ArrayBufferView of the exported public or private >> key." >> >> 6) Add text on import/export for RSA-PSS keys >> >> "24.5. RSA-PSS >> >> 24.5.2. Registration >> >> The recognized algorithm name for this algorithm is "RSA-PSS". >> >> Operation | Parameters | Result >> ================================================ >> sign | RsaPssParams | ArrayBufferView? >> verify | RsaPssParams | boolean? >> generateKey | RsaKeyGenParams | KeyPair? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.4.4. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the RSA key into the format, including any wrap operations >> as >> dictated by the format and wrapAlgorithm. >> 2. If the key is to be wrapped, 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 exported public or private >> key." >> >> 7) Add text on import/export for RSA-OAEP keys >> >> "24.6. RSA-OAEP >> >> 24.6.2. Registration >> >> The recognized algorithm name for this algorithm is "RSA-OAEP". >> >> Operation | Parameters | Result >> ================================================ >> encrypt | RsaOaepParams | ArrayBufferView? >> decrypt | RsaOaepParams | ArrayBufferView? >> generateKey | RsaKeyGenParams | KeyPair? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.6.4. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the RSA key >> 3. If the 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the RSA key into the format >> 2. If the key is to be wrapped, perform the wrap operation defined for >> the wrapAlgorithm >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be an ArrayBufferView of the exported public or private >> key." >> >> 8) Add text on import/export for ECDSA keys >> >> "24.7. ECDSA >> >> 24.7.2. Registration >> >> The recognized algorithm name for this algorithm is "ECDSA". >> >> Operation | Parameters | Result >> ================================================ >> sign | EcdsaParams | ArrayBufferView? >> verify | EcdsaParams | boolean? >> generateKey | EcKeyGenParams | KeyPair? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.7.5. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the ECC 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the ECC key into the format >> 2. If the key is to be wrapped, 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 exported public or private >> key." >> >> 9) Add import/export for AES-CTR keys >> >> "24.9. AES-CTR >> >> 24.9.2. Registration >> >> The recognized algorithm name for this algorithm is "AES-CTR". >> >> Operation | Parameters | Result >> ================================================ >> encrypt | AesCtrParams | ArrayBufferView? >> decrypt | AesCtrParams | ArrayBufferView? >> generateKey | AesKeyGenParams | Key? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.9.5. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the AES key >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be a Key of the imported secret key. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the AES key into the format >> 2. If the key is to be wrapped, perform the wrap operation defined for >> the wrapAlgorithm >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be an ArrayBufferView of the exported secret key." >> >> 10) Add import/export for AES-CBC keys >> >> "24.10. AES-CBC >> >> 24.10.2. Registration >> >> The recognized algorithm name for this algorithm is "AES-CBC". >> >> Operation | Parameters | Result >> ================================================ >> encrypt | AesCbcParams | ArrayBufferView? >> decrypt | AesCbcParams | ArrayBufferView? >> generateKey | AesKeyGenParams | Key? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.10.4. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the AES key. >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be a Key of the imported secret key. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the AES key into the format >> 2. If the key is to be wrapped, perform the wrap operation defined for >> the wrapAlgorithm >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be an ArrayBufferView of the exported secret key." >> >> 11) Add import/export for AES-GCM keys >> >> "24.11. AES-GCM >> >> 24.11.2. Registration >> >> The recognized algorithm name for this algorithm is "AES-GCM". >> >> Operation | Parameters | Result >> ================================================ >> encrypt | AesGcmParams | ArrayBufferView? >> decrypt | AesGcmParams | ArrayBufferView? >> generateKey | AesKeyGenParams | Key? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.11.4. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the AES key >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be a Key of the imported secret key. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the AES key into the format >> 2. If the key is to be wrapped, 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 exported secret key." >> >> 12) Add import/export for HMAC keys >> >> "24.12. HMAC >> >> 24.12.2. Registration >> >> The recognized algorithm name for this algorithm is "HMAC". >> >> Operation | Parameters | Result >> ================================================ >> sign | HmacParams | ArrayBufferView? >> verify | HmacParams | boolean? >> generateKey | HmacKeyGenParams | Key? >> importKey | None | Key? >> exportKey | None | ArrayBufferView? >> >> 24.12.4. HmacKeyGenParams dictionary >> >> dictionary HmacKeyGenParams : AlgorithmParameters { >> // The inner hash function to use. >> AlgorithmIdentifier hash; >> }; >> >> 24.12.5. Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, perform the unwrap operation defined for the >> wrapAlgorithm >> 2. Parse and extract the HMAC 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. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the HMAC key into the format >> 2. If the key is to be wrapped, 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 exported public or private >> key." >> >> 13) Add AES Key wrap algorithm >> >> "24.16 AES Key Wrap >> >> 24.16.1 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. >> >> 24.16.2 Registration >> >> The recognized algorithm name for this algorithm is "AES-KW". >> >> Operation | Parameters | Result >> ================================================ >> generateKey | AesKeyGenParams | Key >> importKey | None | Key >> exportKey | None | ArrayBufferView >> wrap | None | ArrayBufferView >> unwrap | None | Key >> >> 24.16.3 Operations >> >> Import Key >> When importing a key, the resulting KeyImporter shall behave as follows: >> >> 1. Upon invoking import: >> 1. If the key is wrapped, 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, raise an error and terminate >> the >> operation. >> 4. Let result be a Key of the imported public or private key. >> >> Export Key >> When exporting a key, the resulting KeyExporter shall behave as follows: >> >> 1. Upon invoking export: >> 1. Encode the AES Key Wrap key into the format >> 2. If the key is to be wrapped, perform the wrap operation defined for >> the wrapAlgorithm >> 3. If the operation resulted in an error, raise an error and terminate >> the >> operation. >> 4. Let result be an ArrayBufferView of the exported public or private >> key. >> >> Unwrap: >> >> When unwrapping and importing a wrapped key, the following unwrapping steps >> shall be performed first, followed by the steps of the importKey operation >> for the appropriate key algorithm: >> >> 1. If the wrapKey is not an AES Key Wrap key, throw a NotSupporterError and >> terminate the operation >> 2. Apply the RFC5649 unwrapping operation to the provided key, using the >> wrapKey >> 1. If the result of the unwrapping operation is a failure of the data >> integrity check, raise an error and terminate the operation >> 2. Otherwise, if the key data specifies a key algorithm >> 1. if the keyAlgorithm parameter to the import operation 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. >> 2. Otherwise, if the keyAlgorithm parameter is null, set the key algorithm >> to be the key algorithm specified by the key data >> 3. Continue the key import operation using the output of the unwrap >> operation according to the requirements of the key algorithm >> >> Wrap >> >> When wrapping and exporting a key, the resulting key exporter shall behave >> according to the specification of the key algorithm with the following >> additional requirements for the wrapping step: >> >> 1. If the wrapKey is not an AES Key Wrap key, throw a NotSupporterError and >> terminate the operation >> 2. Apply the RFC5649 wrapping operation to the output of the key export >> operation >> 3. Let the result be an ArrayBufferView of the exported, wrapped, key" >> >> 14) Provide an example of wrapped key import >> >> "26.4 Wrapped key import >> >> // The key type, exportability, start and end time are specified in the JWK >> structure. >> // It is assumed JWK is extended to support private and symmetric keys. >> // For example, the following could describe an AES CTR encryption key (note >> this uses values >> // not specified in JWK which so far only addresses public keys. However, >> JWK can be extended >> // on a 'specification required' basis through registration with IANA). >> // >> // keyJwk = { "use" : "enc", "alg" : "A256", "exportable" : false, "key" : >> "56giug87f298gf9724gf9==" } >> // >> // for the purposes of this example, wrappedKeyJwk = AESKeyWrap( keyJwk, >> wrappingKey ) >> >> var keyImporter = window.crypto.createKeyImporter( "jwk", >> wrappedKeyJwk, >> "AES-CTR", >> "AES-KW", >> wrappingKey, >> true, // temporary >> true, // extractable >> [ "encrypt" ] ); >> keyImporter.onComplete = function(event) { >> var key = event.target.result; >> console.log("Imported key ID: " + key.id + "; algorithm " + >> key.algorithm.name + "; exportable " + key.exportable ); >> }; >> keyImporter.import(); >> >> 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 >> >> >
Received on Thursday, 17 January 2013 04:52:57 UTC