Exposing KeyObject fields vs. native JWK support
Now that node has a decent API to deal with cryptographic keys, users have requested features to access parts of keys, e.g. the modulus of an RSA key or the curve name of an EC key. @sam-github
and I came up with the idea to add a .fields
property to KeyObject
which exposes those parts. Other users have encouraged this approach.
I am currently working on a PR for that and the basics are working nicely:
> const keyPairRSA = crypto.generateKeyPairSync('rsa', { modulusLength: 1024 })
undefined
> keyPairRSA.publicKey.fields.modulus
137021253720226911691183972137240610622846133147052915629542163534532873356019104530365068889937816017524544544464479119278509383548598349559040164794055344541073852040420760130374918407240711285194600169474281779365813970973286457910750280768421849742536481361766898914122508451829863613535241209789652127067n
> const keyPairEC = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' })
undefined
> keyPairEC.publicKey.fields.namedCurve
'prime256v1'
One of the reasons users have requested this feature is to be able to implement JWK on top of the native crypto module without having to tap into OpenSSL. However, this would still only make that work in one direction (KeyObject
→ JWK), to create a KeyObject
from JWK, a different API would be necessary to construct keys from their fields.
Another solution would be to natively support JWK. I am not an expert when it comes to JWK, but it shouldn't be difficult to implement as long as we don't need to include algorithm information in the key as WebCrypto does. This approach would extend create***Key
and KeyObject.export
with support for JWK.
If JWK support is not the only reason to access parts of the key, it might still make sense to implement .fields
since JWK was designed for storing keys, not for interacting with its components. For example, .fields
could make use of ES BigInts whereas JWK encodes everything as strings.
So as I see it, there are four options: Implement both, implement one and not the other, or implement none of it. What do you think?
cc @nodejs/crypto
@panva
@mscdex