(function () { var C = typeof window === 'undefined' ? require('./Crypto').Crypto : window.Crypto; // Shortcuts var util = C.util; var charenc = C.charenc; var UTF8 = charenc.UTF8; var Binary = charenc.Binary; C.PBKDF2 = function (password, salt, keylen, options) { // Convert to byte arrays if (password.constructor == String) { password = UTF8.stringToBytes(password); } if (salt.constructor == String) { salt = UTF8.stringToBytes(salt); } /* else, assume byte arrays already */ // Defaults var hasher = (options && options.hasher) || C.SHA1; var iterations = (options && options.iterations) || 1; // Pseudo-random function function PRF(password, salt) { return C.HMAC(hasher, salt, password, { asBytes: true }); } // Generate key var derivedKeyBytes = []; var blockindex = 1; while (derivedKeyBytes.length < keylen) { var block = PRF(password, salt.concat(util.wordsToBytes([blockindex]))); for (var u = block, i = 1; i < iterations; i++) { u = PRF(password, u); for (var j = 0; j < block.length; j++) { block[j] ^= u[j]; } } derivedKeyBytes = derivedKeyBytes.concat(block); blockindex++; } // Truncate excess bytes derivedKeyBytes.length = keylen; return options && options.asBytes ? derivedKeyBytes : options && options.asString ? Binary.bytesToString(derivedKeyBytes) : util.bytesToHex(derivedKeyBytes); }; })();