Web Cryptography API compliance wrt. key import/export
Having gone through Web Cryptography API W3C Editor's Draft here are the discrepancies between the specification and Node.js v16.8.0 Web Crypto API Module actual implementation when it comes to SubtleCrypto.importKey, SubtleCrypto.exportKey, and in the case of RSA-PSS also SubtleCrypto.sign and SubtleCrypto.verify.
The point is to make a catalogue of known issues and open a discussion about how and if to handle them, knowing upfront that not everything can be achieved the possible resolution for some may just be a note in the documentation about the caveats, similar to what the Chromium Project > WebCrypto page lists.
RSASSA-PKCS1-v1_5 importKey "spki"
- does not assert the Public Key type to be an RSA one, it is possible to import any public key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
and throwDataError
if it is not
- proposal: assert that
- does not allow for keys with OID
sha1WithRSAEncryption
,sha256WithRSAEncryption
,sha384WithRSAEncryption
, andsha512WithRSAEncryption
- proposal: document this lack of support since OpenSSL does not support these specialized OIDs
RSASSA-PKCS1-v1_5 importKey "pkcs8"
- does not assert the Private Key type to be an RSA one, it is possible to import any private key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
and throwDataError
if it is not
- proposal: assert that
- does not allow for keys with OID
sha1WithRSAEncryption
,sha256WithRSAEncryption
,sha384WithRSAEncryption
, andsha512WithRSAEncryption
- proposal: document this lack of support since OpenSSL does not support these specialized OIDs
RSA-PSS importKey "spki"
- does not assert the Public Key type to be an RSA or RSA-PSS one, it is possible to import any public key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
or'rsa-pss'
and throwDataError
if it is not
- proposal: assert that
- does not assert that
rsa-pss
keyRSASSA-PSS-params
sequence is present- proposal: when
keyObject.asymmetricKeyType
is'rsa-pss'
assert thatkeyObject.asymmetricKeyDetails.mgf1HashAlgorithm
is notundefined
- proposal: when
- does not assert that
rsa-pss
keyRSASSA-PSS-params
sequencemaskGenAlgorithm
andhashAlgorithm
match the values required for the given algorithm- proposal: when
keyObject.asymmetricKeyType
is'rsa-pss'
assert thatkeyObject.asymmetricKeyDetails.hashAlgorithm
which in turn equals the Node.js normalized digest algorithm name for the WebCrypto algorithm specifiedhash.name
- proposal: when
RSA-PSS exportKey "spki"
- does not respect the requirement to export OID
id-RSASSA-PSS
keys. The OID and content of the key will always depend on the internal KeyObject representation. If it is an'rsa'
key, the result will usersaEncryption
. - does not respect the requirement to export OID
id-RSASSA-PSS
keys withRSASSA-PSS-params
sequence with values depending on the WebCrypto algorithm of the CryptoKey. The behaviour will only be per-spec if the key imported was an RSA-PSS one (given we choose to fix the import steps), but when the imported key was anrsaEncryption
one (allowed) this requirement will not be upheld.
RSA-PSS verify
- fails the verify operation with a rejection when the internal
rsa-pss
KeyObject haskeyObject.asymmetricKeyDetails.saltLength
specified larger than the one requested to be used.- proposal: since the saltLength is not specified at key import but rather the verify operation, according to the spec, if errors are encountered the promise should be resolved with
false
.
- proposal: since the saltLength is not specified at key import but rather the verify operation, according to the spec, if errors are encountered the promise should be resolved with
RSA-PSS importKey "pkcs8"
- does not assert the Private Key type to be an RSA or RSA-PSS one, it is possible to import any private key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
or'rsa-pss'
and throwDataError
if it is not
- proposal: assert that
- does not assert that
rsa-pss
keyRSASSA-PSS-params
sequence is present- proposal: when
keyObject.asymmetricKeyType
is'rsa-pss'
assert thatkeyObject.asymmetricKeyDetails.mgf1HashAlgorithm
is notundefined
- proposal: when
- does not assert that
rsa-pss
keyRSASSA-PSS-params
sequencemaskGenAlgorithm
andhashAlgorithm
match the values required for the given algorithm- proposal: when
keyObject.asymmetricKeyType
is'rsa-pss'
assert thatkeyObject.asymmetricKeyDetails.hashAlgorithm
which in turn equals the Node.js normalized digest algorithm name for the WebCrypto algorithm specifiedhash.name
- proposal: when
RSA-PSS exportKey "pkcs8"
- does not respect the requirement to export OID
id-RSASSA-PSS
keys. The OID and content of the key will always depend on the internal KeyObject representation. If it is an'rsa'
key, the result will usersaEncryption
. - does not respect the requirement to export OID
id-RSASSA-PSS
keys withRSASSA-PSS-params
sequence with values depending on the WebCrypto algorithm of the CryptoKey. The behaviour will only be per-spec if the key imported was an RSA-PSS one (given we choose to fix the import steps), but when the imported key was anrsaEncryption
one (allowed) this requirement will not be upheld.
RSA-PSS sign
- fails the sign operation with an openssl rejection when the internal
rsa-pss
KeyObject haskeyObject.asymmetricKeyDetails.saltLength
specified larger than the one requested to be used.- proposal: since the saltLength is not specified at key import but rather the sign operation, according to the spec, if errors are encountered the promise should be rejected with
OperationError
.
- proposal: since the saltLength is not specified at key import but rather the sign operation, according to the spec, if errors are encountered the promise should be rejected with
RSA-OAEP importKey "spki"
- does not assert the Public Key type to be an RSA one, it is possible to import any public key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
and throwDataError
if it is not
- proposal: assert that
- does not support import of OID
id-RSAES-OAEP
keys- proposal: document this lack of support since OpenSSL does not support? this specialized OID
RSA-OAEP importKey "pkcs8"
- does not assert the Private Key type to be an RSA or RSA-PSS one, it is possible to import any private key
- proposal: assert that
keyObject.asymmetricKeyType
is'rsa'
or'rsa-pss'
and throwDataError
if it is not
- proposal: assert that
- does not support import of OID
id-RSAES-OAEP
keys- proposal: document this lack of support since OpenSSL does not support? this specialized OID
RSA-OAEP exportKey "spki" and "pkcs8"
- given the lack of support for OID
id-RSAES-OAEP
we will always export OIDrsaEncryption
- proposal: document this caveat since OpenSSL does not support? this specialized OID
ECDH exportKey "spki" and "pkcs8"
- given the lack of support for OID
id-ecDH
we will always export OIDid-ecPublicKey
- proposal: document this caveat since OpenSSL does not support? this specialized OID
General
CryptoKey implementation is a rather thin layer on top of a KeyObject instance and that's where most of the import/export OID issues stem from, this is further elevated when 'node.keyObject'
is used as the import key format.