blob: 9c26ddcad30f460000f24e048897c46878f9be88 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
import jssha from "jssha";
const SEARCH_RANGE = 16;
const timeStep = 30;
export function computeTOTPandCheck(
secretKey: Uint8Array,
digits: number,
code: number,
): boolean {
const now = new Date().getTime();
const epoch = Math.floor(Math.round(now / 1000.0) / timeStep);
for (let ms = -SEARCH_RANGE; ms < SEARCH_RANGE; ms++) {
const movingFactor = (epoch + ms).toString(16).padStart(16, "0");
const hmacSha = new jssha("SHA-1", "HEX", {
hmacKey: { value: secretKey, format: "UINT8ARRAY" },
});
hmacSha.update(movingFactor);
const hmac_text = hmacSha.getHMAC("UINT8ARRAY");
const offset = hmac_text[hmac_text.length - 1] & 0xf;
const otp =
(((hmac_text[offset + 0] << 24) +
(hmac_text[offset + 1] << 16) +
(hmac_text[offset + 2] << 8) +
hmac_text[offset + 3]) &
0x7fffffff) %
Math.pow(10, digits);
if (otp == code) return true;
}
return false;
}
const encTable__ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".split("");
export function base32enc(buffer: Uint8Array): string {
let rpos = 0;
let bits = 0;
let vbit = 0;
let result = "";
while (rpos < buffer.length || vbit > 0) {
if (rpos < buffer.length && vbit < 5) {
bits = (bits << 8) | buffer[rpos++];
vbit += 8;
}
if (vbit < 5) {
bits <<= 5 - vbit;
vbit = 5;
}
result += encTable__[(bits >> (vbit - 5)) & 31];
vbit -= 5;
}
return result;
}
// const array = new Uint8Array(256)
// const secretKey = window.crypto.getRandomValues(array)
// console.log(base32enc(secretKey))
|