Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing KeyObject fields vs. native JWK support #26854

Closed
tniessen opened this issue Mar 22, 2019 · 26 comments
Closed

Exposing KeyObject fields vs. native JWK support #26854

tniessen opened this issue Mar 22, 2019 · 26 comments
Labels
crypto Issues and PRs related to the crypto subsystem. discuss Issues opened for discussions and feedbacks. feature request Issues that request new features to be added to Node.js. stale

Comments

@tniessen
Copy link
Member

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

@panva
Copy link
Member

panva commented Mar 22, 2019

I think that create***Key and keyObject.export support for JWK as input and output is the endgame goal. One I would <3

Constructing a PEM from a passed JWK is not hard, it's just annoying and it's something that is either error prone when done by each implementer or requires additional dependencies in the form of asn1.js (that in turn require ~7 more in the form of browser-ready version of assert, BN (doesn't use the built-in when available), and even that doesn't come with the actual asn.1 type definition, so again, prone to errors.

In addition to JWK support I could use .fields because i'd otherwise have to run .export on a passed in PEM/KeyObject to get to those values. This i think would save a roundtrip.

@panva
Copy link
Member

panva commented Mar 22, 2019

For the record here are the bare bone JWK key types and their attributes. Props with ? are required when the key's a private one. All strings are base64url encoded with no padding.

interface JWKOctKey { // createSecretKey
    kty: 'oct',
    k: string
}

interface JWKECKey {
    kty: 'EC'
    crv: 'P-256' | 'P-384' | 'P-521'
    x: string
    y: string
    d?: string
}

interface JWKOKPKey {
    kty: 'OKP'
    crv: 'Ed25519' | 'Ed448' | 'X25519' | 'X448'
    x: string
    d?: string
}

interface JWKRSAKey { // i think covers RSA-PSS keys too
    kty: 'RSA'
    e: string
    n: string
    d?: string
    p?: string
    q?: string
    dp?: string
    dq?: string
    qi?: string
}

@panva
Copy link
Member

panva commented Mar 22, 2019

Just realized the use case i have for implementing both.

In addition to JWK<>PEM two-way support we have the need to use x509 certificates in OpenID Connect/OAuth2.0 for binding tokens to mutual-TLS client certificates. We have a client established property on the server to check for in the certificate, either DN or SAN values. We also want to do x5c (chain) validation.

In those cases i'd pass the certificate(s) to createPublicKey and then use .fields to get to the subject, issuer, subject alternative names etc. That's something JWK support alone won't provide.

So I'd like both.

@panva
Copy link
Member

panva commented Mar 22, 2019

/cc @omsmith

@omsmith
Copy link
Contributor

omsmith commented Mar 22, 2019

While JWK support could be cool, I don't think it precludes implementing fields.

JWK's kty field is defined by this registry: https://www.iana.org/assignments/jose/jose.xhtml#web-key-types

So node would be stuck making a decision about key types that aren't currently specified by JOSE, while the fields may still be valuable (including for an individual looking to make a non-standard JWK)

@ChALkeR
Copy link
Member

ChALkeR commented Mar 22, 2019

cc @nodejs/security-wg

@tniessen
Copy link
Member Author

In those cases i'd pass the certificate(s) to createPublicKey and then use .fields to get to the subject, issuer, subject alternative names etc. That's something JWK support alone won't provide.

The KeyObject API represents cryptographic keys, not certificates. If you pass a certificate, OpenSSL extracts the subjectPublicKeyInfo field and uses it as the key. No other certificate information is retained as part of the KeyObject. Dealing with certificates is still an issue in node.

So node would be stuck making a decision about key types that aren't currently specified by JOSE, while the fields may still be valuable (including for an individual looking to make a non-standard JWK)

I completely agree with you. I don't think we should support exporting those keys.

@panva
Copy link
Member

panva commented Mar 22, 2019

The KeyObject API represents cryptographic keys, not certificates. If you pass a certificate, OpenSSL extracts the subjectPublicKeyInfo field and uses it as the key. No other certificate information is retained as part of the KeyObject. Dealing with certificates is still an issue in node.

Understood, thank you for the clarification.

@tniessen
Copy link
Member Author

Another thing to consider are the names of the fields we are talking about. There are not really standardized names for all of the fields. JWK uses short keys that are close to the mathematical description of the properties. OpenSSL follows this scheme roughly, but some fields still have different names. RFCs for encoding these keys usually use different names that are easier to read: d mod (p - 1) is called dp in JWK, dmp1 in OpenSSL and exponent1 in PKCS#1.

We had a similar discussion around the scrypt API which originally used parameters N, r and p, and we later added aliases (cost, blockSize, parallelization) to make the API more accessible. Similarly, I think I prefer such "verbose" names over abbreviations such as dp or dmp1 here, but we should discuss the naming scheme.

@panva
Copy link
Member

panva commented Mar 22, 2019

Similarly, I think I prefer such "verbose" names over abbreviations such as dp or dmp1 here, but we should discuss the naming scheme.

I agree with a verbose naming scheme.

@sam-github
Copy link
Contributor

sam-github commented Mar 22, 2019

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.

This makes sense, existing create APIs only create from ASN.1, but once .fields exists, I'd expect that keys become round-trippable (eventually):

priv0 = crypto.generateKeyPairSync(type, {...})
priv1 = crypto.createPrivateKey(priv0.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.

Its not clear to me that "native jwk support" is necessarily an alternative to JWK (EDIT: I meant to ".fields"), did you intend to imply that? If the fields structure was identical to JWK, and .fields was acceptable as an input to create[Private|Public|Secret]Key(), then these two options, "native JWK support" and a .fields would be unified, wouldn't they be?

Just to clarify whether I understand this correctly, JOSE is https://jose.readthedocs.io/en/latest/, and has spun off sub-projects, JWK for key representation, JWS for signing, JWE for encryption.

And the relation of JOSE to the WebCrypto API is... what? It looks like WebCrypto implements lower-level cryptographic primitives than JWS and JWE, but that it supports JWK key import/export. Do I understand correctly?

Many node APIs predate the emerging the "standard" APIs, but there is a general drift in node towards exposing the standard APIs as appropriate (an individuals have the energy and time to implement). URL and Performance Timeline for example. I'd bet heavily that in 5 years we have a fetch API, some support for async streams, etc. The evolution is a bit jarring, but leaving aside questions of small-core, and whther we should do this, I have a question:

Would it be possible to expose the WebCrypto API as the primary crypto API? Does it define sufficient primitives, of a wide enough scope, or is its scope of application too limited? For example, I think it has only one-shot symetric encrypt/decrypt APIs, which makes it insufficiently general for non-browser use.

Regardless of future node API directions, I think we all agree on the basic principle: it's our intention that the crypto API evolve to provide sufficient functionality that web-standard (and other) crypto APIs can be implemented using crypto, without native bindings, and if reasonably possible, without excessive use of BER/DER libraries. "excessive" and "reasonable" are obviously a bit "in the eye of the beholder". :-).

WRT. naming: ideally, we would have long form "readable" names, where the names come from a recognizable standard (so we don't have to invent them). JWK is a recognizable standard, and its tempting to use its naming, but it looks problematic:

  1. Its not human readable: https://tools.ietf.org/html/rfc7517#appendix-A.3
  2. Its incomplete: it defines things only if applicable to its use (JSON sign/encrypt). For example, EC curve names are pretty limited, and it doesn't appear to have any DH/DSA support at all: https://www.iana.org/assignments/jose/jose.xhtml#web-key-types

The other options are:

  1. Use names from the PKCS1/SECG/etc ASN.1. They tend to be human readable, well-known, and close to camelCase.
  2. Use names from the OpenSSL API: They appear to be more of a mixture of mathematical and well-known, but have the advantage that if they are used, people who need to ask questions about their meaning or look up more information can go directly the OpenSSL API docs and/or mailing list
  3. Invent our own names. Pro: we can make them great (maybe?), con: people might have to read node_crypto.cc to figure out the maping from the name in our API to the name OpenSSL uses if they have more questions
  4. ...any others?

We'll live with this decision for a long time, so what I'd like to see if its possible (and I know this is a lot of work), is a table of equivalent names for the .field of all key types: JWK, ASN.1, WebCrypto (if this is a thing, it might not be), and OpenSSL API name. The goal would be to 1) pick the best name, and 2) make sure that .fields contains sufficient raw information that JWK, WebCrypto, and ASN.1 (though we already do this internally with OpenSSL) can be implemented on top of it. The second goal is critical, I assume if that's not achieved then .fields just won't be supporting its use-case. The table could eventually be provided in the docs, so its not just a use-once affair.

@sam-github
Copy link
Contributor

Oh, and I've yet to be convinced that any of the raw crypto information should be exposed as numbers. The ASN.1 does not tend to do that. While we all know that some crypto operations are mathematical in nature (but not all, some is just bit operations like shift and XOR, and those aren't best done to numbers), that doesn't mean that users of the broken-out data are going to do math with them. They are mostly, effectively, opaque data that is shoved in and out of various structures, or passed to low-level crypto libs for use (and they may do math with them, but they didn't need or want BigInts in order to do that).

For this reason, and that most languages don't have arbitrary precision integers, key parts are usually treated as opaque data. I think JWK did the right thing here.

@panva
Copy link
Member

panva commented Mar 22, 2019

And the relation of JOSE to the WebCrypto API is... what? It looks like WebCrypto implements lower-level cryptographic primitives than JWS and JWE, but that it supports JWK key import/export. Do I understand correctly?

Yes. JOSE (JWA) restricts / profiles the primitives to form algs - "algorithms", it e.g. strictly defines the saltLength to be used for RSASSA-PSS into an JWA algorithm, e.g. PS256. But there is no relation between JOSE and WebCrypto. The only thing it shares is JWK key representation. And WebCrypto does not even support all of them (OKP).

With the exception of node/openssl unsupported RSA-OAEP-256 you can see all the algorithm implementations using node's crypto here.

For clarity here are the final JOSE-family specs

  • JSON Web Algorithms (JWA) - RFC7518
  • JSON Web Signature (JWS) - RFC7515
  • JSON Web Encryption (JWE) - RFC7516
  • JSON Web Key (JWK) - RFC7517
  • JSON Web Key (JWK) Thumbprint - RFC7638
  • CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures JOSE - RFC8037

I'm not including JWT because it's just JWS profile using compact serialization and specific claim definition (type and processing), i'm also omitting JWS format extensions

Options 1 and 3 sound good to me,

  1. Use names from the PKCS1/SECG/etc ASN.1. They tend to be human readable, well-known, and close to camelCase.
  2. Invent our own names. Pro: we can make them great (maybe?), con: people might have to read node_crypto.cc to figure out the maping from the name in our API to the name OpenSSL uses if they have more questions

But frankly, since @tniessen clarified .fields just returns what's in subjectPublicKeyInfo when cert is passed in I think it's not that useful anymore (the main additional use-case i wanted to cross off was dealing with certificates) considering we'd could have an API like so.

const jwk = {
  kty: 'EC',
  crv: 'P-256',
  x: 'gskvlmd8hChm_hxtH4oyDC2rizV1jwK4exTn3icBxu8',
  y: '0El8NqTyybjkEJ2grVUDK1BdPo49OF1pmCJCD92_h-Y'
};
const keyObject = createPublicKey(jwk);
keyObject.export({ format: 'jwk' });

// jwk members equal to exported members

And we could forget about naming because JWK cut out the work for us and we're just supporting another key representation, not extending the API with new methods and properties per se.

@tniessen
Copy link
Member Author

tniessen commented Mar 22, 2019

Would it be possible to expose the WebCrypto API as the primary crypto API? Does it define sufficient primitives, of a wide enough scope, or is its scope of application too limited? For example, I think it has only one-shot symetric encrypt/decrypt APIs, which makes it insufficiently general for non-browser use.

It is certainly possible to implement WebCrypto as part of node core, but I still believe that it is not a sufficient standard for non-browser applications. It has no streaming interface and there is a lot of overhead in each operation (e.g. by using Promises for everything, even when synchronous operation would be much faster). There is also only a handful of operations and algorithms.

The goal would be to 1) pick the best name, and 2) make sure that .fields contains sufficient raw information that JWK, WebCrypto, and ASN.1 (though we already do this internally with OpenSSL) can be implemented on top of it.

Locally, I have been using RFC names when possible. The fields are sufficient to be used to implement JWK on top of them, but if that is their primary use, we might be better off supporting JWK directly.

Oh, and I've yet to be convinced that any of the raw crypto information should be exposed as numbers. The ASN.1 does not tend to do that. While we all know that some crypto operations are mathematical in nature (but not all, some is just bit operations like shift and XOR, and those aren't best done to numbers), that doesn't mean that users of the broken-out data are going to do math with them. They are mostly, effectively, opaque data that is shoved in and out of various structures, or passed to low-level crypto libs for use (and they may do math with them, but they didn't need or want BigInts in order to do that).

For this reason, and that most languages don't have arbitrary precision integers, key parts are usually treated as opaque data. I think JWK did the right thing here.

So far, I sticked to the data types OpenSSL is using in its public APIs, and those are mostly BIGNUMs. If we decide to use strings instead, then .fields is much closer to JWK than to actually providing useful data to users in my opinion.

@sam-github
Copy link
Contributor

@panva I think that maybe eventually const keyObject = createPublicKey(jwk); keyObject.export({ format: 'jwk' }); could end up in core, but that the first most important step is to support the underlying key info that will allow you to implement that yourself.

since @tniessen clarified .fields just returns what's in subjectPublicKeyInfo when cert is passed in I think it's not that useful anymore

I'm puzzled by this. For two reasons. 1, one of your primary use-cases of JWK import/export is met by .fields even without an X.509 parse output not being in .fields (or so I thought). 2, X.509 certs are not keys, they are wrappers around keys. I don't think jamming full X.509 cert decodes into a publicKey.fields is helpful. Among other things, it means that when you import a key, what .fields it has depends on its original format, which is odd, if its encrypted/unencrypted, PKCS1/, SPKI, PFX, X.509-DER, or X.509-PEM should not affect the contents of publicKey.fields.

I do think a X.509 decode (and, ultimately, support for the range of OpenSSL APIs for import/export/create of cert requests, certs, PKCS7 and CMS, PFX, etc.) would be desierable. X.509 decode is relatively easy, the code is there, I might do it soon, but TLS1.3 is hight priority ATM.

@tniessen

If we decide to use strings instead, then .fields is much closer to JWK than to actually providing useful data to users in my opinion.

Can you describe what use you think users would make of BigInts coming out of .fields?

The only uses I can think of is if they want to experiment with implementing, for example, cryptographic primitives (for example, ECMQV) that are not supported by Node.js. Or perhaps they are cryptography/math students, and want to directly implement some of the existing algorithms to explore how they are done. I've done this before, but with ruby arbitrary precision numbers, when I was trying to get a deeper understanding of RSA.

Both those use-cases are supported by outputting strings, though with a loss of efficiency since conversion to a JS numeric type is required. That conversion cost would be dwarfed by the actual overhead of most crypto algorithms, I think.

The most common use of the .fields will be transport/import/export/display-to-humans of keys, and that is best done with strings. So, making the most common representation the default seems right to me.

We could have our cake and eat it too by having .fields and .fields.bigint or .fields and .numbers (those names suck, but just an example), or even .fields('numeric') and .fields('octet').

@sam-github
Copy link
Contributor

Locally, I have been using RFC names when possible. The fields are sufficient to be used to implement JWK on top of them, but if that is their primary use, we might be better off supporting JWK directly.

I don't think its the primary use-case, its just the primary use-case of @panva who is the most helpful and active potential user ATM. ;-) Also, we won't be able to support fields of anything not covered by JWK (such as DSA or DH keys).

I think the .fields is the first useful layer. Later, maybe, adding direct JWK support might be useful (or maybe everyone wanting it will want to do JWE and JWS, so will be using a JOSE module and won't care if the import/export is directly implemented by crypto, or just enabled).

@panva
Copy link
Member

panva commented Mar 22, 2019

I'm puzzled by this. For two reasons. 1, one of your primary use-cases of JWK import/export is met by .fields even without an X.509 parse output not being in .fields (or so I thought).

Not import, no, having .fields is fine for exporting, but doesn't solve import and the whole roundtrip on its own.

See @tniessen's first message:

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.

2, X.509 certs are not keys, they are wrappers around keys. I don't think jamming full X.509 cert decodes into a publicKey.fields is helpful. Among other things, it means that when you import a key, what .fields it has depends on its original format, which is odd, if its encrypted/unencrypted, PKCS1/, SPKI, PFX, X.509-DER, or X.509-PEM should not affect the contents of publicKey.fields.

I can tell you there is use for getting contents of a cert. But let's table that for now, i agree with you that .fields should yield the same result regardless of what the input was.

I am totally behind building in layers, so if the idea is

  1. .fields out of a keyobject
  2. fields into a keyobject
  3. extend create***Key and keyobject.export with JWK that uses 1 and 2 internally

💯% fine

I don't think its the primary use-case, its just the primary use-case of @panva who is the most helpful and active potential user ATM. ;-) Also, we won't be able to support fields of anything not covered by JWK (such as DSA or DH keys).

Primary use-case aside (haven't seen a cryptography/math student make a node feature request building on top of KeyObject, i think they're all using python :trollface:), non-JWK defined key types are probably the best argument for starting with the fields layer.

@bnoordhuis bnoordhuis added crypto Issues and PRs related to the crypto subsystem. discuss Issues opened for discussions and feedbacks. labels Mar 24, 2019
@sam-github
Copy link
Contributor

Just re-read. JWK uses strings for keys, but the strings are b64url encoded? That is pretty specific... I'm about +0 on JWK in/out support ATM, but still +lots on a .fields, though I'm starting to wonder, maybe it should be .fields(encoding), where encoding defaults to buffer (common in node.js, and fast and easy to construct from the underlying openssl data), but can also be bigint, 'hex' (a hex encoded string), b64 and b64url (assuming this is different from b64). Buffer is all that is strictly necessary...., but creating a buffer then converting to actual desired type might be expensive... but then again, premature optimization? Anyhow, if it is a method, not a getter/property, we have the ability to add encodings later. If its a getter/property, we have to privilege one use-case.

An equivalent KeyObject.from() API would also be needed, I assume.

@panva
Copy link
Member

panva commented Aug 13, 2019

An equivalent KeyObject.from() API would also be needed, I assume.

Much needed, yes.

Today we're mostly working with Buffer instances that we get from asn.1 parser implementations.

KeyObject.from() would probably get messy if it had to support all those encodings as well.

Defining b64url as a first-class encoding citizen is also tricky since its application can be with or without padding, so base64url and base64url-padded.

@tniessen
Copy link
Member Author

What are possible use cases for .fields apart from JWK? nodejs/webcrypto#16 could be solved using .fields, but it could technically also be solved using JWK and some conversions. Also, if we decided to implement JWK in node, it most likely would not be WebCrypto-compliant due to missing key_ops, use, ext etc., so we would need additional JWK-specific logic in the WebCrypto package anyway.

maybe it should be .fields(encoding), where encoding defaults to buffer

Or an option to keep it extensible: .fields({ encoding }).

Defining b64url as a first-class encoding citizen is also tricky since its application can be with or without padding, so base64url and base64url-padded.

base64url is one of the many oddities of WebCrypto / JWK. The conversion between base64 and base64url is relatively easy to do outside of node core, so unless we decide to implement JWK, we should probably not use it (or promote its use).

@tniessen
Copy link
Member Author

Related problem: nodejs/webcrypto#17

@sam-github
Copy link
Contributor

What are possible use cases for .fields apart from JWK?

Like JWK, any crypto scheme, algorithm, protocol, or format that is not currently supported needs access to the raw key data. I don't know the current list of "what node or openssl doesn't support", but it has to be a non-empty set!

.fields({ encoding })

👍

b64url ....

Right, forget I mentioned it, it sounds too fringe, and easily implemented in JWK.

Also, the point that JWK has a number of features that node doesn't support doesn't, in my mind, exclude us just doing the parts we can, but I do think just exposing the fields and letting WebCrypto (and any other crypto extensions there might be out there) have access is a way for Node.js to just focus on mechanism, and let npm packages use those mechanisms as they need.

JWK could always be added into node later if it was useful.

@jasnell jasnell added the feature request Issues that request new features to be added to Node.js. label Jun 26, 2020
jasnell added a commit to jasnell/node that referenced this issue Oct 7, 2020
jasnell added a commit that referenced this issue Oct 8, 2020
Fixes: #678
Refs: #26854

Signed-off-by: James M Snell <[email protected]>

PR-URL: #35093
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
joesepi pushed a commit to joesepi/node that referenced this issue Jan 8, 2021
Fixes: nodejs#678
Refs: nodejs#26854

Signed-off-by: James M Snell <[email protected]>

PR-URL: nodejs#35093
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
@panva
Copy link
Member

panva commented Apr 16, 2021

With JWK export/import now being part of the KeyObject.export/create*Key APIs and asymmetricKeyDetails, is there still a need for this kind of representation?

@github-actions
Copy link
Contributor

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

1 similar comment
@github-actions
Copy link
Contributor

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot added the stale label Mar 24, 2022
@github-actions
Copy link
Contributor

There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.

For more information on how the project manages feature requests, please consult the feature request management document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crypto Issues and PRs related to the crypto subsystem. discuss Issues opened for discussions and feedbacks. feature request Issues that request new features to be added to Node.js. stale
Projects
None yet
Development

No branches or pull requests

7 participants