From 6ac63678ccc94646f538b771ad7d68adcdaa4f32 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jun 2026 21:29:19 +0100 Subject: [PATCH 1/2] feat: add `create-hmac` to preferred manifest --- docs/modules/create-hmac.md | 57 +++++++++++++++++++++++++++++++++++++ manifests/preferred.json | 30 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 docs/modules/create-hmac.md diff --git a/docs/modules/create-hmac.md b/docs/modules/create-hmac.md new file mode 100644 index 00000000..a1f0e65d --- /dev/null +++ b/docs/modules/create-hmac.md @@ -0,0 +1,57 @@ +--- +description: Modern alternatives to the `crypto-js` package for cryptographic operations +--- + +# Replacements for `create-hmac` + +## `crypto.createHmac` (native, Node.js) + +```js +import { createHmac } from 'node:crypto' // [!code ++] +import createHmac from 'create-hmac' // [!code --] + +const secret = 'secret-key' +const data = 'message-to-sign' + +const hash = createHmac('sha256', secret).update(data).digest('hex') +``` + +## `crypto.subtle.sign` (native, browser) + +```js +const encoder = new TextEncoder() + +async function generateHMAC(secret, data) { + const key = await crypto.subtle.importKey( + "raw", + encoder.encode(secret), + { name: "HMAC", hash: "SHA-256" }, + false, + ["sign"] + ) + + const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data)) + + return new Uint8Array(signature).toHex() +} + +const secret = 'secret-key' +const data = 'message-to-sign' + +const hash = await generateHMAC(secret, data) +``` + +## `@noble/hashes` + +```js +import { hmac } from '@noble/hashes/hmac.js' // [!code ++] +import { sha256 } from '@noble/hashes/sha256.js' // [!code ++] +import { bytesToHex } from '@noble/hashes/utils.js' // [!code ++] +import createHmac from 'create-hmac' // [!code --] + +const secret = 'secret-key' +const data = 'message-to-sign' + +const hash = createHmac('sha256', secret).update(data).digest('hex') // [!code --] +const hash = bytesToHex(hmac(sha256, secret, data)) // [!code ++] +``` diff --git a/manifests/preferred.json b/manifests/preferred.json index b0d0abfd..d4eb4bb6 100644 --- a/manifests/preferred.json +++ b/manifests/preferred.json @@ -174,6 +174,16 @@ "replacements": ["cpx2"], "url": {"type": "e18e", "id": "cpx"} }, + "create-hmac": { + "type": "module", + "moduleName": "create-hmac", + "replacements": [ + "crypto.createHmac", + "crypto.subtle.sign", + "@noble/hashes" + ], + "url": {"type": "e18e", "id": "create-hmac"} + }, "cross-fetch": { "type": "module", "moduleName": "cross-fetch", @@ -2774,6 +2784,11 @@ "type": "documented", "replacementModule": "@materializecss/materialize" }, + "@noble/hashes": { + "id": "@noble/hashes", + "type": "documented", + "replacementModule": "@noble/hashes" + }, "@placemarkio/tokml": { "id": "@placemarkio/tokml", "type": "documented", @@ -2989,6 +3004,12 @@ }, "url": {"type": "mdn", "id": "Web/API/Web_Crypto_API"} }, + "crypto.createHmac": { + "id": "crypto.createHmac", + "type": "native", + "url": {"type": "node", "id": "api/crypto.html#cryptocreatehmacalgorithm-key-options"}, + "nodeFeatureId": {"moduleName": "crypto", "exportName": "createHmac"} + }, "crypto.randomUUID": { "id": "crypto.randomUUID", "type": "native", @@ -2998,6 +3019,15 @@ }, "url": {"type": "mdn", "id": "Web/API/Crypto/randomUUID"} }, + "crypto.subtle.sign": { + "id": "crypto.subtle.sign", + "type": "native", + "webFeatureId": { + "featureId": "web-cryptography", + "compatKey": "api.SubtleCrypto.sign" + }, + "url": {"type": "mdn", "id": "Web/API/SubtleCrypto/sign"} + }, "crypto.timingSafeEqual": { "id": "crypto.timingSafeEqual", "type": "native", From 60dd386380306e240e67d17ec7c23625de7db400 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 23 Jun 2026 21:43:20 +0100 Subject: [PATCH 2/2] format and fix description --- docs/modules/create-hmac.md | 12 ++++++------ manifests/preferred.json | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/modules/create-hmac.md b/docs/modules/create-hmac.md index a1f0e65d..dd99ef00 100644 --- a/docs/modules/create-hmac.md +++ b/docs/modules/create-hmac.md @@ -1,5 +1,5 @@ --- -description: Modern alternatives to the `crypto-js` package for cryptographic operations +description: Modern alternatives to the `create-hmac` package for HMAC --- # Replacements for `create-hmac` @@ -22,15 +22,15 @@ const hash = createHmac('sha256', secret).update(data).digest('hex') const encoder = new TextEncoder() async function generateHMAC(secret, data) { - const key = await crypto.subtle.importKey( - "raw", + const key = await crypto.subtle.importKey( + 'raw', encoder.encode(secret), - { name: "HMAC", hash: "SHA-256" }, + { name: 'HMAC', hash: 'SHA-256' }, false, - ["sign"] + ['sign'] ) - const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data)) + const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(data)) return new Uint8Array(signature).toHex() } diff --git a/manifests/preferred.json b/manifests/preferred.json index d4eb4bb6..7897b4d3 100644 --- a/manifests/preferred.json +++ b/manifests/preferred.json @@ -3007,7 +3007,10 @@ "crypto.createHmac": { "id": "crypto.createHmac", "type": "native", - "url": {"type": "node", "id": "api/crypto.html#cryptocreatehmacalgorithm-key-options"}, + "url": { + "type": "node", + "id": "api/crypto.html#cryptocreatehmacalgorithm-key-options" + }, "nodeFeatureId": {"moduleName": "crypto", "exportName": "createHmac"} }, "crypto.randomUUID": {