Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 | 5x 1x 4x 4x 4x 4x 4x 4x 4x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 7x | import { createHmac } from 'crypto'; class HKDF { /** * @param {string} hash * @param {Buffer} salt * @param {string} initialKey */ constructor(hash, salt, initialKey) { if (!HKDF.hashList[hash]) { throw new Error('not supported hash method'); } this.hashMethod = hash; this.hashLength = HKDF.hashList[hash]; this.salt = salt; this.initialKey = initialKey; const hmac = createHmac(hash, this.salt); hmac.update(this.initialKey); this.prk = hmac.digest(); } /** * Expands the pseudorandom key to the desired length. * @param {string} [info] - Optional context and application-specific information. * @param {number} [size] - The length of the output keying material in bytes. * @returns {Buffer} - The expanded keying material. */ expand(info = '', size = 32) { /** @type {string | Buffer} */ let pre = ''; const output = []; const numBlocks = Math.ceil(size / this.hashLength); for (let i = 0; i < numBlocks; i++) { const hmac = createHmac(this.hashMethod, this.prk); hmac.update(pre); hmac.update(info); hmac.update(Buffer.alloc(1, i + 1)); pre = hmac.digest(); output.push(pre); } return Buffer.concat(output, size); } } /** * A static property that maps hash algorithm names to their output lengths in bytes. * @type {{ [key: string]: number }} */ HKDF.hashList = { sha256: 32, sha224: 54, sha512: 64 }; export default HKDF; |