Skip to content

Commit

Permalink
allow hmac signing
Browse files Browse the repository at this point in the history
  • Loading branch information
dtinth committed Apr 11, 2024
1 parent 858de47 commit 979a719
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ <h1>NFC onboarder</h1>
<label for="url">Configure URL:</label>
<input type="text" id="url" value="" name="url" />
<span class="hint"
>{sn} will be replaced with the tag's serial number</span
>{sn} will be replaced with the tag's serial number,
{hmac:<i>key</i>} will be replaced with the HMAC of the tag's
serial number using the specified key</span
>
</p>
<button type="submit" id="begin">Begin</button>
Expand All @@ -161,7 +163,9 @@ <h1>NFC onboarder</h1>
<label for="targetUrl">Target URL configured:</label>
<input type="text" id="targetUrl" readonly value="https://" />
<span class="hint"
>{sn} will be replaced with the tag's serial number</span
>{sn} will be replaced with the tag's serial number,
{hmac:<i>key</i>} will be replaced with the HMAC of the tag's
serial number using the specified key</span
>
</div>
<button id="scan">Activate NFC reader</button>
Expand Down Expand Up @@ -222,6 +226,22 @@ <h1>NFC tag has been onboarded.</h1>
} 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();
Expand Down Expand Up @@ -253,7 +273,23 @@ <h1>NFC tag has been onboarded.</h1>
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;
}
Expand Down

0 comments on commit 979a719

Please sign in to comment.