Hmac.js
2.3 KB
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
63
64
65
66
67
68
69
import { Utf8 } from "./lib/encoder/Utf8";
export class Hmac {
constructor(hasher, key) {
this._hasher = hasher;
// Convert string to WordArray, else assume WordArray already
if (typeof key == "string") {
key = Utf8.parse(key);
}
const hasherBlockSize = hasher.blockSize;
const hasherBlockSizeBytes = hasherBlockSize * 4;
// Allow arbitrary length keys
if (key.nSigBytes > hasherBlockSizeBytes) {
key = hasher.finalize(key);
}
// Clamp excess bits
key.clamp();
const oKey = this._oKey = key.clone();
const iKey = this._iKey = key.clone();
const oKeyWords = oKey.words;
const iKeyWords = iKey.words;
for (let i = 0; i < hasherBlockSize; i++) {
oKeyWords[i] ^= 0x5c5c5c5c;
iKeyWords[i] ^= 0x36363636;
}
iKey.nSigBytes = hasherBlockSizeBytes;
oKey.nSigBytes = hasherBlockSizeBytes;
// Set initial values
this.reset();
}
/**
* Resets this Hmac to its initial state.
*
* @example
* hmacHasher.reset();
*/
reset() {
this._hasher.reset();
this._hasher.update(this._iKey);
}
/**
* Updates this Hmac with a message.
*
* @param {Word32Array|string} messageUpdate The message to append.
* @return {Hmac} This Hmac instance.
* @example
* hmacHasher.update('message');
* hmacHasher.update(wordArray);
*/
update(messageUpdate) {
this._hasher.update(messageUpdate);
return this;
}
/**
* Finalizes the Hmac computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param {Word32Array|string} messageUpdate (Optional) A final message update.
* @return {Word32Array} The Hmac.
* @example
* var hmac = hmacHasher.finalize();
* var hmac = hmacHasher.finalize('message');
* var hmac = hmacHasher.finalize(wordArray);
*/
finalize(messageUpdate) {
const innerHash = this._hasher.finalize(messageUpdate);
this._hasher.reset();
return this._hasher.finalize(this._oKey.clone().concat(innerHash));
}
}