From 979a7195dcd9373ba9301b836f57cb1ba7ab9310 Mon Sep 17 00:00:00 2001
From: dtinth on MBP M1
Date: Fri, 12 Apr 2024 03:40:10 +0700
Subject: [PATCH] allow hmac signing
---
index.html | 42 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/index.html b/index.html
index a8c0f2b..a73724d 100644
--- a/index.html
+++ b/index.html
@@ -143,7 +143,9 @@ NFC onboarder
Configure URL:
{sn} will be replaced with the tag's serial number {sn} will be replaced with the tag's serial number,
+ {hmac:key } will be replaced with the HMAC of the tag's
+ serial number using the specified key
Begin
@@ -161,7 +163,9 @@ NFC onboarder
Target URL configured:
{sn} will be replaced with the tag's serial number {sn} will be replaced with the tag's serial number,
+ {hmac:key } will be replaced with the HMAC of the tag's
+ serial number using the specified key
Activate NFC reader
@@ -222,6 +226,22 @@ NFC tag has been onboarded.
} else {
setScreen("welcome");
}
+ async function hmac(str, key) {
+ const strBytes = new TextEncoder().encode(str);
+ const keyBytes = new TextEncoder().encode(key);
+ const cryptoKey = await crypto.subtle.importKey(
+ "raw",
+ keyBytes,
+ { name: "HMAC", hash: "SHA-256" },
+ false,
+ ["sign"]
+ );
+ const signature = await crypto.subtle.sign("HMAC", cryptoKey, strBytes);
+ // Format as hex
+ return Array.from(new Uint8Array(signature))
+ .map((b) => b.toString(16).padStart(2, "0"))
+ .join("");
+ }
$("#scan").addEventListener("click", async () => {
try {
const reader = new NDEFReader();
@@ -253,7 +273,23 @@ NFC tag has been onboarded.
2
);
const sn = serialNumber.replace(/:/g, "");
- const expectedUrl = url.replaceAll("{sn}", sn);
+
+ const hmacRegex = /\{hmac:([^}]+)\}/g;
+ const hmacMap = new Map();
+ const promises = [];
+ url.replaceAll(hmacRegex, (_, key) => {
+ promises.push(
+ hmac(sn, key).then((sig) => {
+ hmacMap.set(key, sig);
+ })
+ );
+ });
+ if (promises.length) {
+ await Promise.all(promises);
+ }
+ const expectedUrl = url
+ .replaceAll("{sn}", sn)
+ .replaceAll(hmacRegex, (_, key) => hmacMap.get(key));
for (const snSpan of document.querySelectorAll(".sn")) {
snSpan.textContent = serialNumber;
}