packages/js-crypto-hkdf/src/hkdf.js
async function rfc5869(master, hash, length, info, salt){
  const len = params.hashes[hash].hashSize;

  // RFC5869 Step 1 (Extract)
  const prk = await hmac.compute(salt, master, hash);

  // RFC5869 Step 2 (Expand)
  let t = new Uint8Array([]);
  const okm = new Uint8Array(Math.ceil(length / len) * len);
  const uintInfo = new Uint8Array(info);
  for(let i = 0; i < Math.ceil(length / len); i++){
    const concat = new Uint8Array(t.length + uintInfo.length + 1);
    concat.set(t);
    concat.set(uintInfo, t.length);
    concat.set(new Uint8Array([i+1]), t.length + uintInfo.length);
    t = await hmac.compute(prk, concat, hash);
    okm.set(t, len * i);
  }
  return okm.slice(0, length);
}
async function rfc5869(master, hash, length, info, salt){
  const len = params.hashes[hash].hashSize;

  // RFC5869 Step 1 (Extract)
  const prk = await hmac.compute(salt, master, hash);

  // RFC5869 Step 2 (Expand)
  let t = new Uint8Array([]);
  const okm = new Uint8Array(Math.ceil(length / len) * len);
  const uintInfo = new Uint8Array(info);
  for(let i = 0; i < Math.ceil(length / len); i++){
    const concat = new Uint8Array(t.length + uintInfo.length + 1);
    concat.set(t);
    concat.set(uintInfo, t.length);
    concat.set(new Uint8Array([i+1]), t.length + uintInfo.length);
    t = await hmac.compute(prk, concat, hash);
    okm.set(t, len * i);
  }
  return okm.slice(0, length);
}
async function rfc5869 ( master , hash , length , info , salt ) { const len = params . hashes [ hash ] . hashSize ; // RFC5869 Step 1 (Extract) const prk = await hmac . compute ( salt , master , hash ) ; // RFC5869 Step 2 (Expand) let t = new Uint8Array ( [ ] ) ; const okm = new Uint8Array ( Math . ceil ( length / len ) * len ) ; const uintInfo = new Uint8Array ( info ) ; for ( let i = 0 ; i < Math . ceil ( length / len ) ; i ++ ) { const concat = new Uint8Array ( t . length + uintInfo . length + 1 ) ; concat . set ( t ) ; concat . set ( uintInfo , t . length ) ; concat . set ( new Uint8Array ( [ i + 1 ] ) , t . length + uintInfo . length ) ; t = await hmac . compute ( prk , concat , hash ) ; okm . set ( t , len * i ) ; } return okm . slice ( 0 , length ) ; }
Naive implementation of RFC5869 in PureJavaScript
@param {Uint8Array} master - Master secret to derive the key.
@param {String} hash - Name of hash algorithm used to derive the key.
@param {Number} length - Intended length of derived key.
@param {String} info - String for information field of HKDF.
@param {Uint8Array} salt - Byte array of salt.
@return {Promise<Uint8Array>} - Derived key.
Naive implementation of RFC5869 in PureJavaScript