Skip to content

Complete the WebCrypto API implementation to cover the full specification#1045

Merged
xeioex merged 5 commits intonginx:masterfrom
xeioex:webcrypto
Apr 6, 2026
Merged

Complete the WebCrypto API implementation to cover the full specification#1045
xeioex merged 5 commits intonginx:masterfrom
xeioex:webcrypto

Conversation

@xeioex
Copy link
Copy Markdown
Contributor

@xeioex xeioex commented Apr 4, 2026

This complete the WebCrypto API implementation to cover the full W3C specification.

This branch adds the remaining algorithms and operations that were missing:

  • Ed25519: sign/verify with EdDSA keys (import, export, generate in all formats)
  • X25519: key agreement via deriveBits/deriveKey (import, export, generate in all formats)
  • AES-KW: key wrapping algorithm for wrapKey/unwrapKey
  • crypto.randomUUID(): UUID v4 generation
  • wrapKey/unwrapKey: full implementation replacing the previous stubs, supporting both raw and JWK formats with all cipher algorithms

With these changes, njs implements all 12 SubtleCrypto methods, all 13 algorithms (RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH, Ed25519, X25519, AES-CTR, AES-CBC, AES-GCM, AES-KW, HMAC, HKDF, PBKDF2), all 4 digest algorithms, all 4 key formats (raw, pkcs8, spki, jwk), crypto.getRandomValues(), and crypto.randomUUID(). Both the njs and QuickJS engine backends are updated.

Ed25519/X25519 and AES-KW are conditionally compiled based on OpenSSL feature detection (auto/openssl), so builds against older OpenSSL versions remain functional.

Test plan

  • WebCrypto test suite — 16 test files covering:
    • Ed25519: sign/verify roundtrip, all format exports, RFC 8032 vectors, tampered data/wrong key negative tests, algorithm mismatch errors
    • X25519: deriveBits/deriveKey, all format exports, RFC 7748 vector, algorithm mismatch errors
    • AES-KW: RFC 3394 vectors, JWK import/export, size validation errors, usage errors
    • wrapKey/unwrapKey: multi-algorithm wrap/unwrap including JWK format, non-extractable/usage errors
    • randomUUID: format, version/variant bits, uniqueness

@xeioex xeioex changed the title Webcrypto Complete the WebCrypto API implementation to cover the full specification Apr 4, 2026
xeioex added 3 commits April 3, 2026 23:25
Removed the incorrect "alg":"RS256" field from RSA JWK test data
files.  The field is optional per RFC 7517, and the value RS256
(RSASSA-PKCS1-v1_5) was wrong for tests that use RSA-OAEP and
RSA-PSS algorithms.  Node.js correctly rejects JWK imports when
the "alg" field does not match the requested algorithm.

The hash mismatch negative test was updated to use an inline JWK
with an explicit "alg" field instead of the shared file.

This ensures: `test/test262 --binary=node test/webcrypto` pass.
Supports 128, 192, and 256-bit key sizes with generateKey,
importKey, and exportKey operations in raw and JWK formats.

Also fixed deriveKey to accept 192-bit AES key lengths.
@VadimZhestikov
Copy link
Copy Markdown
Contributor

It seems X25519 should have its own feature probe instead of piggybacking on NJS_HAVE_ED25519.

Right now auto/openssl checks only EVP_PKEY_ED25519, but the algorithm table enables both Ed25519 and X25519 under #if (NJS_HAVE_ED25519).

This works if both are always present together in all supported crypto backends, but that assumption is not encoded in the build checks.

Would you mind adding a separate EVP_PKEY_X25519 probe / macro, or at least documenting why the shared gate is guaranteed safe?

xeioex added 2 commits April 6, 2026 14:47
Implemented Ed25519 sign/verify/generateKey/importKey/exportKey
Supports raw, PKCS8, SPKI, and JWK (OKP) key formats.

Implemented X25519 deriveBits/deriveKey/generateKey/importKey/
exportKey.
Added JWK format support to unwrapKey: decrypted data is parsed as
JSON and imported through the shared import path.
@xeioex
Copy link
Copy Markdown
Contributor Author

xeioex commented Apr 6, 2026

@VadimZhestikov

Would you mind adding a separate EVP_PKEY_X25519 probe / macro, or at least documenting why the shared gate is guaranteed safe?

Both Ed25519 and X25519 share the same Curve25519 implementation and were introduced together in all supported crypto backends: OpenSSL 1.1.1, LibreSSL 3.7.0, BoringSSL (rolling-release mode), and AWS-LC (forked from BoringSSL after 2019 with both *25519 already supported). No known build configuration in any of these libraries enables one without the other. Added a comment in auto/openssl documenting this.

Copy link
Copy Markdown
Contributor

@VadimZhestikov VadimZhestikov left a comment

Choose a reason for hiding this comment

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

Looks good

@xeioex xeioex merged commit 79d5b18 into nginx:master Apr 6, 2026
2 checks passed
@xeioex xeioex deleted the webcrypto branch April 6, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants