UNPKG

mima-kit

Version:

mima-kit is a cryptographic suite implemented in TypeScript. The goal is to provide an easy-to-use cryptographic library. mima-kit 是一个使用 TypeScript 实现的密码学套件。目标是提供一个简单易用的密码学库。

45 lines (44 loc) 1.76 kB
import { U8 } from '../core/utils'; import { hmac } from './hmac'; import { sha1 } from './sha1'; /** * 生成 HOTP (基于计数的一次性密码) * * Generate HOTP (HMAC-based One-Time Password) * * @param {Uint8Array} secret - 密钥 / Secret key * @param {Uint8Array} counter - 计数器 / Counter * @param {KeyHash} mac - 带密钥的加密散列算法 / Keyed Hashing Algorithm (default: HMAC-SHA1) * @returns {U8} - 返回的 HOTP 字节数组 / HOTP byte array */ function hotp(secret, counter, mac = hmac(sha1)) { const HS = mac(secret, counter); const offset = HS[HS.length - 1] & 0x0f; return HS.slice(offset, offset + 4); } export function totp(args) { if (args instanceof Uint8Array) { const K = args; const C = U8.fromBI(BigInt(Math.floor(Date.now() / 30000)), 8, false); const HS = hotp(K, C, hmac(sha1)); const OTP = 0 | ((HS[0] & 0x7f) << 24) | ((HS[1] & 0xff) << 16) | ((HS[2] & 0xff) << 8) | (HS[3] & 0xff); return (OTP % 1_000_000).toString().padStart(6, '0'); } return (secret) => { let { mac = hmac(sha1), current = Date.now(), epoch = 0, step = 30000, counter = 0, digits = 6, } = args || {}; if (!counter) { const T = BigInt(Math.floor((current - epoch) / step)); counter = U8.fromBI(T, 8, false); } if (!(counter instanceof Uint8Array)) { counter = U8.fromBI(BigInt(counter), 8, false); } const BIN = hotp(secret, counter, mac); const OTP = 0 | ((BIN[0] & 0x7f) << 24) | ((BIN[1] & 0xff) << 16) | ((BIN[2] & 0xff) << 8) | (BIN[3] & 0xff); return (OTP % 10 ** digits).toString().padStart(digits, '0'); }; }