native-browser-otp
Version:
Lightweight library for generating TOTP and HOTP codes using browser's native Web Cryptography API. Perfect for implementing two-factor authentication (2FA) in web applications.
36 lines (35 loc) • 1.1 kB
JavaScript
import decode from "base32-decode";
async function createHmac(secret, text) {
const key = await crypto.subtle.importKey(
"raw",
decode(secret, "RFC4648"),
{ name: "HMAC", hash: { name: "SHA-1" } },
false,
["sign", "verify"]
);
const hash = await crypto.subtle.sign("HMAC", key, text);
return new Uint8Array(hash);
}
function truncate(hash) {
const offset = hash[hash.length - 1] & 15;
return (hash[offset] & 127) << 24 | (hash[offset + 1] & 255) << 16 | (hash[offset + 2] & 255) << 8 | hash[offset + 3] & 255;
}
async function hotp(secret, counter) {
const text = new Uint8Array(8);
for (let i = text.length - 1; i >= 0; i--) {
text[i] = counter & 255;
counter >>= 8;
}
const hash = await createHmac(secret, new Uint8Array(text));
const binary = truncate(hash);
const otp = binary % 1e6;
return String(otp).padStart(6, "0");
}
async function totp(secret) {
const code = await hotp(secret, Math.floor(Date.now() / 3e4));
return code;
}
function timeLeft() {
return 30 - Math.floor(Date.now() / 1e3) % 30;
}
export { hotp, timeLeft, totp };