Skip to content

crypto: add raw key formats support to the KeyObject APIs#62240

Open
panva wants to merge 4 commits intonodejs:mainfrom
panva:raw-formats
Open

crypto: add raw key formats support to the KeyObject APIs#62240
panva wants to merge 4 commits intonodejs:mainfrom
panva:raw-formats

Conversation

@panva
Copy link
Member

@panva panva commented Mar 13, 2026

notable-change PRs with changes that should be highlighted in changelogs. 👇

Add raw key format support (raw-public, raw-private, raw-seed) to KeyObject.prototype.export(), crypto.createPrivateKey(), and crypto.createPublicKey() for applicable asymmetric keys (EC, CFRG curves, ML-DSA, ML-KEM, and SLH-DSA). This intrinsically means it is supported as input to the other cryptographic APIs as well.


This also adds a much needed docs section on the different key formats and their usage examples.

Also wire these to their existing Web Cryptography APIs counterparts and remove the unnecessary KeyExportJob. The KeyExportJob classes were removed because the export operations they performed are not computationally expensive. They're just serialization of already-available key data (SPKI, PKCS8, raw bytes). Running them as async CryptoJobs on the libuv thread pool added unnecessary overhead and complexity for operations that complete instantly.

This is not a semver-major but bits of it depend on #62178 which is. I will try to open a partial backport to 25/24.


Key Type vs Format matrix
Key Type 'pem' 'der' 'jwk' 'raw-public' 'raw-private' 'raw-seed'
'dh'
'dsa'
'ec'
'ed25519'
'ed448'
'ml-dsa-44'
'ml-dsa-65'
'ml-dsa-87'
'ml-kem-512'
'ml-kem-768'
'ml-kem-1024'
'rsa-pss'
'rsa'
'slh-dsa-sha2-128f'
'slh-dsa-sha2-128s'
'slh-dsa-sha2-192f'
'slh-dsa-sha2-192s'
'slh-dsa-sha2-256f'
'slh-dsa-sha2-256s'
'slh-dsa-shake-128f'
'slh-dsa-shake-128s'
'slh-dsa-shake-192f'
'slh-dsa-shake-192s'
'slh-dsa-shake-256f'
'slh-dsa-shake-256s'
'x25519'
'x448'

@panva panva added crypto Issues and PRs related to the crypto subsystem. notable-change PRs with changes that should be highlighted in changelogs. experimental Issues and PRs related to experimental features. webcrypto dont-land-on-v20.x PRs that should not land on the v20.x-staging branch and should not be released in v20.x. dont-land-on-v22.x PRs that should not land on the v22.x-staging branch and should not be released in v22.x. dont-land-on-v24.x PRs that should not land on the v24.x-staging branch and should not be released in v24.x. dont-land-on-v25.x PRs that should not land on the v25.x-staging branch and should not be released in v25.x. labels Mar 13, 2026
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/crypto

@github-actions
Copy link
Contributor

The notable-change PRs with changes that should be highlighted in changelogs. label has been added by @panva.

Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section.

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Mar 13, 2026
@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 82.76699% with 71 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.71%. Comparing base (abff716) to head (0f81de3).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/crypto/crypto_keys.cc 66.90% 11 Missing and 35 partials ⚠️
lib/internal/crypto/cfrg.js 71.42% 8 Missing ⚠️
lib/internal/crypto/ec.js 86.53% 7 Missing ⚠️
lib/internal/crypto/rsa.js 68.18% 7 Missing ⚠️
lib/internal/crypto/keys.js 97.77% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62240      +/-   ##
==========================================
- Coverage   91.60%   89.71%   -1.90%     
==========================================
  Files         337      676     +339     
  Lines      140745   206706   +65961     
  Branches    21807    39617   +17810     
==========================================
+ Hits       128933   185448   +56515     
- Misses      11588    13413    +1825     
- Partials      224     7845    +7621     
Files with missing lines Coverage Δ
lib/internal/crypto/ml_dsa.js 95.04% <100.00%> (-0.14%) ⬇️
lib/internal/crypto/ml_kem.js 91.89% <100.00%> (-0.24%) ⬇️
lib/internal/crypto/webcrypto.js 96.36% <100.00%> (+0.03%) ⬆️
src/crypto/crypto_dh.cc 67.37% <ø> (ø)
src/crypto/crypto_dh.h 11.11% <ø> (ø)
src/crypto/crypto_ec.cc 68.55% <ø> (ø)
src/crypto/crypto_ec.h 12.50% <ø> (ø)
src/crypto/crypto_keys.h 60.71% <ø> (ø)
src/crypto/crypto_rsa.cc 64.45% <ø> (ø)
src/crypto/crypto_rsa.h 58.33% <ø> (ø)
... and 6 more

... and 448 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@panva panva added the semver-minor PRs that contain new features and should be released in the next minor version. label Mar 13, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@panva
Copy link
Member Author

panva commented Mar 14, 2026

cc @ChALkeR @paulmillr FYI as it makes working with ECC much much easier

@paulmillr
Copy link

Great improvement!

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@panva panva added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Mar 16, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@ChALkeR
Copy link
Member

ChALkeR commented Mar 16, 2026

Yes, this is great, thanks!

(I did not review the impl though)

@panva
Copy link
Member Author

panva commented Mar 16, 2026

@ChALkeR doing so would go a long way to be able to land this with more confidence.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot
Copy link
Collaborator

@panva panva requested a review from anonrig March 17, 2026 15:55
@panva panva added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Mar 20, 2026
Add raw key format support (raw-public, raw-private, raw-seed) to
KeyObject.prototype.export(), crypto.createPrivateKey(),
and crypto.createPublicKey() for applicable asymmetric keys (EC,
CFRG curves, ML-DSA, ML-KEM, and SLH-DSA).

Also wire these to the Web Cryptography APIs and remove the unnecessary
KeyExportJob. The KeyExportJob classes were removed because the export
operations they performed are not computationally expensive. They're
just serialization of already-available key data (SPKI, PKCS8, raw
bytes). Running them as async CryptoJobs on the libuv thread pool added
unnecessary overhead and complexity for operations that complete
instantly.
Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes LGTM but the doc changes are a bit too repetitive and verbose... non-blocking tho.

[`crypto.createPrivateKey()`][] for usage details.

`'raw-public'` is generally the fastest way to import a public key.
`'raw-private'` and `'raw-seed'` are not always faster than other formats
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running the benchmarks locally, this claim seems a bit inconsistent. raw-public for EC is the slowest when running the benchmarks locally and raw-public does not appear to provide benefit for ed25519 verify.

These are minor issues but I do question if we should be making claims in the docs of which is faster since that's something that can reasonably vary as time goes on.

Copy link
Member Author

@panva panva Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha. Thanks. I left the benchmark export to be compressed, so re-import is decompressing (re-calculating the y-coordinate). Do you think i should change the default export to be uncompressed then? I think so.

Image with uncompressed ec raw-public import, the claim that raw-public is generally the fastest is right (given that the ec export was done uncompressed)

image

Verify throughput is obviously dominated by the actual cryptography, not by the import itself.

Copy link
Member Author

@panva panva Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into ec JWK separately > #62396

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. crypto Issues and PRs related to the crypto subsystem. dont-land-on-v20.x PRs that should not land on the v20.x-staging branch and should not be released in v20.x. dont-land-on-v22.x PRs that should not land on the v22.x-staging branch and should not be released in v22.x. dont-land-on-v24.x PRs that should not land on the v24.x-staging branch and should not be released in v24.x. dont-land-on-v25.x PRs that should not land on the v25.x-staging branch and should not be released in v25.x. experimental Issues and PRs related to experimental features. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version. webcrypto

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants