Skip to content

Instantly share code, notes, and snippets.

@alastorid
Last active September 26, 2023 09:54
Show Gist options
  • Save alastorid/9e13823968e048003414eb99ffc57069 to your computer and use it in GitHub Desktop.
Save alastorid/9e13823968e048003414eb99ffc57069 to your computer and use it in GitHub Desktop.
use it at your own risk #rfc6238
function genTotp(s) {
const a = 'abcdefghijklmnopqrstuvwxyz234567', t = BigInt(Math.floor(Date.now() / 30000)), b = new Uint8Array(8);
let bits = '', bytes = new Uint8Array(s.length * 5 / 8);
for (let c of s) bits += a.indexOf(c).toString(2).padStart(5, '0');
for (let i = 0, j = 0; i + 8 <= bits.length; i += 8, j++) bytes[j] = parseInt(bits.substr(i, 8), 2);
for (let i = 0; i < 8; i++) b[7 - i] = Number(t >> (BigInt(i) * 8n));
return crypto.subtle.importKey("raw", bytes.buffer, { name: "HMAC", hash: "SHA-1" }, false, ["sign"]).then(k =>
crypto.subtle.sign("HMAC", k, b)
).then(s => {
const h = new Uint8Array(s), o = h[19] & 0x0f, v = (h[o] << 24 | h[o + 1] << 16 | h[o + 2] << 8 | h[o + 3]) & 0x7fffffff;
return (v % 1000000).toString().padStart(6, '0');
});
}
genTotp("your_base32_key").then(console.log);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment