function pbkdf2Generate(P, S, c, dkLen,
                       hmacAlg=Ci.nsICryptoHMAC.SHA1, hmacLen=20) {

    // We don't have a default in the algo itself, as NSS does.
    // Use the constant.
    if (!dkLen) {
      dkLen = SYNC_KEY_DECODED_LENGTH;
    }

    function F(S, c, i, h) {

      function XOR(a, b, isA) {
        if (a.length != b.length) {
          return false;
        }

        let val = [];
        for (let i = 0; i < a.length; i++) {
          if (isA) {
            val[i] = a[i] ^ b[i];
          } else {
            val[i] = a.charCodeAt(i) ^ b.charCodeAt(i);
          }
        }

        return val;
      }

      let ret;
      let U = [];

      /* Encode i into 4 octets: _INT */
      let I = [];
      I[0] = String.fromCharCode((i >> 24) & 0xff);
      I[1] = String.fromCharCode((i >> 16) & 0xff);
      I[2] = String.fromCharCode((i >> 8) & 0xff);
      I[3] = String.fromCharCode(i & 0xff);

      U[0] = CryptoUtils.digestBytes(S + I.join(''), h);
      for (let j = 1; j < c; j++) {
        U[j] = CryptoUtils.digestBytes(U[j - 1], h);
      }

      ret = U[0];
      for (let j = 1; j < c; j++) {
        ret = CommonUtils.byteArrayToString(XOR(ret, U[j]));
      }

      return ret;
    }

    let l = Math.ceil(dkLen / hmacLen);
    let r = dkLen - ((l - 1) * hmacLen);

    // Reuse the key and the hasher. Remaking them 4096 times is 'spensive.
    let h = CryptoUtils.makeHMACHasher(hmacAlg,
                                       CryptoUtils.makeHMACKey(P));

    let T = [];
    for (let i = 0; i < l;) {
      T[i] = F(S, c, ++i, h);
    }

    let ret = "";
    for (let i = 0; i < l-1;) {
      ret += T[i++];
    }
    ret += T[l - 1].substr(0, r);

    return ret;
  }
/**
   * PBKDF2 implementation in Javascript.
   *
   * The arguments to this function correspond to items in
   * PKCS #5, v2.0 pp. 9-10
   *
   * P: the passphrase, an octet string:              e.g., "secret phrase"
   * S: the salt, an octet string:                    e.g., "DNXPzPpiwn"
   * c: the number of iterations, a positive integer: e.g., 4096
   * dkLen: the length in octets of the destination
   *        key, a positive integer:                  e.g., 16
   * hmacAlg: The algorithm to use for hmac
   * hmacLen: The hmac length
   *
   * The default value of 20 for hmacLen is appropriate for SHA1.  For SHA256,
   * hmacLen should be 32.
   *
   * The output is an octet string of length dkLen, which you
   * can encode as you wish.
   */
PBKDF2 implementation in Javascript.
The arguments to this function correspond to items in
PKCS #5, v2.0 pp. 9-10



The default value of 20 for hmacLen is appropriate for SHA1.  For SHA256,
hmacLen should be 32.

The output is an octet string of length dkLen, which you
can encode as you wish.
PBKDF2 implementation in Javascript . The arguments to this function correspond to items in PKCS #5 v2 . 0 pp . 9 - 10 The default value of 20 for hmacLen is appropriate for SHA1 . For SHA256 hmacLen should be 32 . The output is an octet string of length dkLen which you can encode as you wish .
function pbkdf2Generate(P, S, c, dkLen,
                       hmacAlg=Ci.nsICryptoHMAC.SHA1, hmacLen=20) {
    if (!dkLen) {
      dkLen = SYNC_KEY_DECODED_LENGTH;
    }
    function F(S, c, i, h) {
      function XOR(a, b, isA) {
        if (a.length != b.length) {
          return false;
        }
        let val = [];
        for (let i = 0; i < a.length; i++) {
          if (isA) {
            val[i] = a[i] ^ b[i];
          } else {
            val[i] = a.charCodeAt(i) ^ b.charCodeAt(i);
          }
        }
        return val;
      }
      let ret;
      let U = [];
      let I = [];
      I[0] = String.fromCharCode((i >> 24) & 0xff);
      I[1] = String.fromCharCode((i >> 16) & 0xff);
      I[2] = String.fromCharCode((i >> 8) & 0xff);
      I[3] = String.fromCharCode(i & 0xff);
      U[0] = CryptoUtils.digestBytes(S + I.join(''), h);
      for (let j = 1; j < c; j++) {
        U[j] = CryptoUtils.digestBytes(U[j - 1], h);
      }
      ret = U[0];
      for (let j = 1; j < c; j++) {
        ret = CommonUtils.byteArrayToString(XOR(ret, U[j]));
      }
      return ret;
    }
    let l = Math.ceil(dkLen / hmacLen);
    let r = dkLen - ((l - 1) * hmacLen);
    let h = CryptoUtils.makeHMACHasher(hmacAlg,
                                       CryptoUtils.makeHMACKey(P));
    let T = [];
    for (let i = 0; i < l;) {
      T[i] = F(S, c, ++i, h);
    }
    let ret = "";
    for (let i = 0; i < l-1;) {
      ret += T[i++];
    }
    ret += T[l - 1].substr(0, r);
    return ret;
  }
function pbkdf2Generate ( P , S , c , dkLen , hmacAlg = Ci . nsICryptoHMAC . SHA1 , hmacLen = 20 ) { if ( ! dkLen ) { dkLen = SYNC_KEY_DECODED_LENGTH ; } function F ( S , c , i , h ) { function XOR ( a , b , isA ) { if ( a . length != b . length ) { return false ; } let val = [ ] ; for ( let i = 0 ; i < a . length ; i ++ ) { if ( isA ) { val [ i ] = a [ i ] ^ b [ i ] ; } else { val [ i ] = a . charCodeAt ( i ) ^ b . charCodeAt ( i ) ; } } return val ; } let ret ; let U = [ ] ; let I = [ ] ; I [ 0 ] = String . fromCharCode ( ( i >> 24 ) & 0xff ) ; I [ 1 ] = String . fromCharCode ( ( i >> 16 ) & 0xff ) ; I [ 2 ] = String . fromCharCode ( ( i >> 8 ) & 0xff ) ; I [ 3 ] = String . fromCharCode ( i & 0xff ) ; U [ 0 ] = CryptoUtils . digestBytes ( S + I . join ( '' ) , h ) ; for ( let j = 1 ; j < c ; j ++ ) { U [ j ] = CryptoUtils . digestBytes ( U [ j - 1 ] , h ) ; } ret = U [ 0 ] ; for ( let j = 1 ; j < c ; j ++ ) { ret = CommonUtils . byteArrayToString ( XOR ( ret , U [ j ] ) ) ; } return ret ; } let l = Math . ceil ( dkLen / hmacLen ) ; let r = dkLen - ( ( l - 1 ) * hmacLen ) ; let h = CryptoUtils . makeHMACHasher ( hmacAlg , CryptoUtils . makeHMACKey ( P ) ) ; let T = [ ] ; for ( let i = 0 ; i < l ; ) { T [ i ] = F ( S , c , ++ i , h ) ; } let ret = "" ; for ( let i = 0 ; i < l - 1 ; ) { ret += T [ i ++ ] ; } ret += T [ l - 1 ] . substr ( 0 , r ) ; return ret ; }
PBKDF2 implementation in Javascript.
PBKDF2 implementation in Javascript .
// We don't have a default in the algo itself, as NSS does. // Use the constant. /* Encode i into 4 octets: _INT */ // Reuse the key and the hasher. Remaking them 4096 times is 'spensive.