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
JavaScript
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');
};
}