-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathhmac.js
47 lines (39 loc) · 1.35 KB
/
hmac.js
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
import sha256 from './sha256.js';
import {
uint8ArrayAppend as append,
stringToUtf8
} from './utils.js';
export default function hmac(hashFn, blockSizeBits, secret, message, returnBytes) {
if(!(message instanceof Uint8Array)) {
throw new Error('message must be of Uint8Array');
}
const blockSizeBytes = blockSizeBits / 8;
const ipad = new Uint8Array(blockSizeBytes);
const opad = new Uint8Array(blockSizeBytes);
ipad.fill(0x36);
opad.fill(0x5c);
const secretBytes = stringToUtf8(secret);
let paddedSecret;
if(secretBytes.length <= blockSizeBytes) {
const diff = blockSizeBytes - secretBytes.length;
paddedSecret = new Uint8Array(blockSizeBytes);
paddedSecret.set(secretBytes);
} else {
paddedSecret = hashFn(secretBytes);
}
const ipadSecret = ipad.map((value, index) => {
return value ^ paddedSecret[index];
});
const opadSecret = opad.map((value, index) => {
return value ^ paddedSecret[index];
});
// HMAC(message) = H(K' XOR opad || H(K' XOR ipad || message))
const result = hashFn(
append(opadSecret, hashFn(append(ipadSecret, message), true)),
returnBytes);
return result;
}
if(process.env.TEST) {
console.log(sha256(stringToUtf8('abc')));
console.log(hmac(sha256, 512, 'test', stringToUtf8('abc')));
}