fix(ext/node): improve Node.js crypto compatibility#32690
Merged
bartlomieju merged 12 commits intodenoland:mainfrom Mar 17, 2026
Merged
fix(ext/node): improve Node.js crypto compatibility#32690bartlomieju merged 12 commits intodenoland:mainfrom
bartlomieju merged 12 commits intodenoland:mainfrom
Conversation
When passing an options object like `{ key: keyObject, padding: ... }`
to `crypto.publicEncrypt` or `crypto.privateDecrypt`, the `prepareKey`
function now correctly handles `KeyObject` instances in the `key`
property. Previously it only accepted strings and buffers, throwing
"Invalid key type" for KeyObjects.
Enables the `test-crypto-oaep-zero-length.js` Node.js compat test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `crypto.hash()` function now accepts an options object as the third argument with `outputEncoding` and `outputLength` properties, matching Node.js behavior. This enables XOF hash functions (SHAKE128/256) to specify custom output lengths via `crypto.hash()`. For non-XOF algorithms, validates that `outputLength` matches the algorithm's actual digest size, throwing a descriptive error otherwise. Enables the `test-crypto-oneshot-hash-xof.js` Node.js compat test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…errors Match Node.js error format for cipher/decipher padding errors by using proper OpenSSL error codes (ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH, ERR_OSSL_EVP_BAD_DECRYPT) and adding reason property to errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement crypto.publicDecrypt using raw RSA public key operation with PKCS1 type 1 unpadding. Fix privateEncrypt to use actual private key RSA operation instead of incorrectly delegating to public key encrypt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix asymmetricKeyDetails for RSA-PSS keys without params to use camelCase property names (modulusLength, publicExponent) by adding missing serde rename_all attribute. Implement RSA-PSS public key SPKI DER export. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d curves/key types Use Node.js-compatible error codes (ERR_CRYPTO_JWK_UNSUPPORTED_CURVE, ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE) and messages for JWK export errors. Change error class from TypeError to Error to match Node.js. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Default DSA divisorLength to 160 for modulusLength <= 1024 to match OpenSSL/Node.js behavior. Fix clippy needless-range-loop warning. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ecrypt KeyObject was listed in the buffer parameter type but never handled — getArrayBufferOrView would throw at runtime. The buffer parameter is data to encrypt/decrypt, not a key. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
kajukitli
approved these changes
Mar 14, 2026
Contributor
kajukitli
left a comment
There was a problem hiding this comment.
Reviewed the changes. No issues found.
nathanwhit
approved these changes
Mar 16, 2026
Member
nathanwhit
left a comment
There was a problem hiding this comment.
LGTM aside from not using proper node errors
| if (!this._autoPadding && this._cache.cache.byteLength != bs) { | ||
| throw new Error("Invalid final block size"); | ||
| const err = new Error("wrong final block length"); | ||
| (err as any).code = "ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH"; |
Member
There was a problem hiding this comment.
Use a proper node error class instead of just a plain error
Use proper NodeError class instead of plain Error with manual .code assignment for cipher final block and decrypt errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Node.js tests expect a `reason` property on OpenSSL-style errors. Add an opensslError helper that creates a NodeError and sets reason. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This test requires encrypted PEM export support (cipher+passphrase in privateKeyEncoding) which is not yet implemented. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
kajukitli
approved these changes
Mar 17, 2026
Contributor
kajukitli
left a comment
There was a problem hiding this comment.
Reviewed the changes with full repo context. No issues found.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
crypto.publicDecryptand fixcrypto.privateEncryptto use correct RSA private key operation (PKCS1 type 1 padding)KeyObjectinpublicEncrypt/privateDecryptoptions objectcrypto.hash()for XOF digests (shake128/shake256)NodeErrorclass with OpenSSL-compatible error codes andreasonproperty for cipher padding errors (ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH,ERR_OSSL_EVP_BAD_DECRYPT)asymmetricKeyDetailsto use camelCase property names and enable SPKI DER exportNewly passing Node.js compat tests
test-crypto-oaep-zero-length.jstest-crypto-oneshot-hash-xof.jstest-crypto-padding.jstest-crypto-keygen-no-rsassa-pss-params.jstest-crypto-keygen-invalid-parameter-encoding-ec.jstest-crypto-keygen-invalid-parameter-encoding-dsa.jsNote:
test-crypto-publicDecrypt-fails-first-time.jsrequires encrypted PEM export support (cipher+passphrase inprivateKeyEncoding) which is not yet implemented — left as a TODO.Test plan
./x test-node crypto_cipher)🤖 Generated with Claude Code