@@ -37,7 +37,7 @@ const DEFAULT_PERIOD = 30
37
37
* @param {string } [options.charSet='0123456789'] - The character set to use, defaults to the numbers 0-9.
38
38
* @returns {Promise<string> } The generated HOTP.
39
39
*/
40
- async function generateHOTP (
40
+ export async function generateHOTP (
41
41
secret ,
42
42
{
43
43
counter = 0 ,
@@ -56,28 +56,31 @@ async function generateHOTP(
56
56
)
57
57
const signature = await crypto . subtle . sign ( 'HMAC' , key , byteCounter )
58
58
const hashBytes = new Uint8Array ( signature )
59
- // offset is always the last 4 bits of the signature; 0-15
60
- const offset = hashBytes [ hashBytes . length - 1 ] & 0xf
59
+ // offset is always the last 4 bits of the signature; its value: 0-15
60
+ const offset = hashBytes [ hashBytes . length - 1 ] & 0xf
61
61
62
62
let hotpVal = 0n
63
63
if ( digits === 6 ) {
64
64
// stay compatible with the authenticator apps and only use the bottom 32 bits of BigInt
65
65
hotpVal = 0n |
66
- BigInt ( ( hashBytes [ offset ] & 0x7f ) ) << 24n |
67
- BigInt ( ( hashBytes [ offset + 1 ] ) ) << 16n |
68
- BigInt ( ( hashBytes [ offset + 2 ] ) ) << 8n |
66
+ BigInt ( hashBytes [ offset ] & 0x7f ) << 24n |
67
+ BigInt ( hashBytes [ offset + 1 ] ) << 16n |
68
+ BigInt ( hashBytes [ offset + 2 ] ) << 8n |
69
69
BigInt ( hashBytes [ offset + 3 ] )
70
70
} else {
71
71
// otherwise create a 64bit value from the hashBytes
72
72
hotpVal = 0n |
73
- BigInt ( ( hashBytes [ offset ] & 0x7f ) ) << 56n |
74
- BigInt ( ( hashBytes [ offset + 1 ] ) ) << 48n |
75
- BigInt ( ( hashBytes [ offset + 2 ] ) ) << 40n |
76
- BigInt ( ( hashBytes [ offset + 3 ] ) ) << 32n |
77
- BigInt ( ( hashBytes [ offset + 4 ] ) ) << 24n |
78
- BigInt ( ( hashBytes [ offset + 5 ] ) ) << 16n |
79
- BigInt ( ( hashBytes [ offset + 6 ] ) ) << 8n |
80
- BigInt ( hashBytes [ offset + 7 ] )
73
+ BigInt ( hashBytes [ offset ] & 0x7f ) << 56n |
74
+ BigInt ( hashBytes [ offset + 1 ] ) << 48n |
75
+ BigInt ( hashBytes [ offset + 2 ] ) << 40n |
76
+ BigInt ( hashBytes [ offset + 3 ] ) << 32n |
77
+ BigInt ( hashBytes [ offset + 4 ] ) << 24n |
78
+
79
+ // we have only 20 hashBytes; if offset is 15 these indexes are out of the hashBytes
80
+ // fallback to zero
81
+ BigInt ( hashBytes [ offset + 5 ] ?? 0n ) << 16n |
82
+ BigInt ( hashBytes [ offset + 6 ] ?? 0n ) << 8n |
83
+ BigInt ( hashBytes [ offset + 7 ] ?? 0n )
81
84
}
82
85
83
86
let hotp = ''
0 commit comments