[njs] WebCrypto: added support for HMAC as derivedKeyAlgorithm.

noreply at nginx.com noreply at nginx.com
Thu May 8 16:31:02 UTC 2025


details:   https://github.com/nginx/njs/commit/7bbb8c2753ea236a1202f4664532f06da97a0d0e
branches:  master
commit:    7bbb8c2753ea236a1202f4664532f06da97a0d0e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed, 7 May 2025 19:11:24 -0700
description:
WebCrypto: added support for HMAC as derivedKeyAlgorithm.

In crypto.subtle.deriveKey().

This closes #905 issue on Github.

---
 external/njs_webcrypto_module.c |  3 +++
 external/qjs_webcrypto_module.c |  3 +++
 test/webcrypto/derive.t.mjs     | 30 ++++++++++++++++++++++++++----
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c
index d2918891..6f4b49e1 100644
--- a/external/njs_webcrypto_module.c
+++ b/external/njs_webcrypto_module.c
@@ -1532,6 +1532,9 @@ njs_ext_derive(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             break;
 
+        case NJS_ALGORITHM_HMAC:
+            break;
+
         default:
             njs_vm_internal_error(vm, "not implemented deriveKey: \"%V\"",
                                   njs_algorithm_string(dalg));
diff --git a/external/qjs_webcrypto_module.c b/external/qjs_webcrypto_module.c
index a28a8581..29aea329 100644
--- a/external/qjs_webcrypto_module.c
+++ b/external/qjs_webcrypto_module.c
@@ -1756,6 +1756,9 @@ qjs_webcrypto_derive(JSContext *cx, JSValueConst this_val, int argc,
 
             break;
 
+        case QJS_ALGORITHM_HMAC:
+            break;
+
         default:
             JS_ThrowTypeError(cx, "not implemented deriveKey: \"%s\"",
                               qjs_algorithm_string(dalg));
diff --git a/test/webcrypto/derive.t.mjs b/test/webcrypto/derive.t.mjs
index 5ac13459..4d865da3 100644
--- a/test/webcrypto/derive.t.mjs
+++ b/test/webcrypto/derive.t.mjs
@@ -3,6 +3,16 @@ includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCr
 flags: [async]
 ---*/
 
+function has_usage(usage, x) {
+    for (let i = 0; i < usage.length; i++) {
+        if (x === usage[i]) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 async function test(params) {
     let r;
     let encoder = new TextEncoder();
@@ -12,10 +22,17 @@ async function test(params) {
     if (params.derive === "key") {
         let key = await crypto.subtle.deriveKey(params.algorithm, keyMaterial,
                                                 params.derivedAlgorithm,
-                                                true, [ "encrypt", "decrypt" ]);
+                                                true, params.usage);
+
+        if (has_usage(params.usage, "encrypt")) {
+            r = await crypto.subtle.encrypt(params.derivedAlgorithm, key,
+                                            encoder.encode(params.text));
+
+        } else if (has_usage(params.usage, "sign")) {
+            r = await crypto.subtle.sign(params.derivedAlgorithm, key,
+                                         encoder.encode(params.text));
+        }
 
-        r = await crypto.subtle.encrypt(params.derivedAlgorithm, key,
-                                        encoder.encode(params.text));
     } else {
 
         r = await crypto.subtle.deriveBits(params.algorithm, keyMaterial, params.length);
@@ -63,7 +80,8 @@ let derive_tsuite = {
           name: "AES-GCM",
           length: 256,
           iv: "55667788556677885566778855667788"
-        }
+        },
+        usage: [ "encrypt", "decrypt" ]
     },
 
     tests: [
@@ -92,6 +110,10 @@ let derive_tsuite = {
 
         { algorithm: { name: "HKDF" }, optional: true,
           expected: "18ea069ee3317d2db02e02f4a228f50dc80d9a2396e6" },
+        { algorithm: { name: "HKDF" },
+          derivedAlgorithm: { name: "HMAC", hash: "SHA-256", length: 256 },
+          usage: [ "sign", "verify" ], optional: true,
+          expected: "0b06bd37de54c08cedde2cbb649d6f26d066acfd51717d83b52091e2ae6829c2" },
         { derive: "bits", algorithm: { name: "HKDF" }, optional: true,
           expected: "e089c7491711306c69e077aa19fae6bfd2d4a6d240b0d37317d50472d7291a3e" },
 ]};


More information about the nginx-devel mailing list