Skip to content

Exposing KeyObject fields vs. native JWK support #26854

Closed
@tniessen

Description

@tniessen

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.discussIssues opened for discussions and feedbacks.feature requestIssues that request new features to be added to Node.js.stale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions