Created
June 11, 2017 11:48
-
-
Save nwrox/c4979b3f470c8484fa39d74207d07b44 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert') | |
, crypto = require('crypto') | |
class HKDFBufferGenerator { | |
constructor(alg, ikm, info, salt, size) { | |
this._alg = alg | |
this._ikm = ikm | |
this._info = info | |
this._salt = salt | |
this._size = size | |
} | |
getOKM(){ | |
const hashLen = crypto.createHash(this._alg).digest().length | |
, n = Math.ceil(this._size / hashLen) | |
if(n >= 256) | |
throw Error('HKDF cannot generate more than 255 blocks of HashLen size'); | |
if (this._size > 255 * hashLen) | |
throw Error('HKDF may only be used for 255 * HashLen bytes of output'); | |
this._info = Buffer.from(this._info) | |
this._salt = this._salt || Buffer.alloc(hashLen) | |
this._prk = crypto.createHmac(this._alg, this._salt).update(this._ikm).digest() | |
const buffer = nSeq(n).reduce((acc, curr) => { | |
curr = Buffer.concat([acc, this._info, asciiBuffer(curr)]) | |
curr = crypto.createHmac(this._alg, this._prk).update(curr).digest() | |
return Buffer.concat([acc, curr]) | |
}, Buffer.alloc(0)) | |
return buffer.slice(0, this._size) | |
} | |
getPRK() { | |
return this._prk | |
} | |
} | |
const asciiBuffer = (n) => Buffer.from( String.fromCharCode(n + 1) ) | |
const nSeq = (n) => [...Array(n).keys()] | |
// test vectors: case 1 | |
const ikm = Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex') | |
, salt = Buffer.from('000102030405060708090a0b0c', 'hex') | |
, info = Buffer.from('f0f1f2f3f4f5f6f7f8f9', 'hex') | |
, gen = new HKDFBufferGenerator('sha256', ikm, info, salt, 42) | |
, okm = '3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865' | |
, prk = '077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5' | |
, outOKM = gen.getOKM().toString('hex') | |
, outPRK = gen.getPRK().toString('hex') | |
assert.equal(outOKM, okm) | |
assert.equal(outPRK, prk) | |
console.log(outOKM, '\n\n', outPRK) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment