PBKDF2.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. (function(){
  2. var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
  3. // Shortcuts
  4. var util = C.util,
  5. charenc = C.charenc,
  6. UTF8 = charenc.UTF8,
  7. Binary = charenc.Binary;
  8. C.PBKDF2 = function (password, salt, keylen, options) {
  9. // Convert to byte arrays
  10. if (password.constructor == String) password = UTF8.stringToBytes(password);
  11. if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
  12. /* else, assume byte arrays already */
  13. // Defaults
  14. var hasher = options && options.hasher || C.SHA1,
  15. iterations = options && options.iterations || 1;
  16. // Pseudo-random function
  17. function PRF(password, salt) {
  18. return C.HMAC(hasher, salt, password, { asBytes: true });
  19. }
  20. // Generate key
  21. var derivedKeyBytes = [],
  22. blockindex = 1;
  23. while (derivedKeyBytes.length < keylen) {
  24. var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
  25. for (var u = block, i = 1; i < iterations; i++) {
  26. u = PRF(password, u);
  27. for (var j = 0; j < block.length; j++) block[j] ^= u[j];
  28. }
  29. derivedKeyBytes = derivedKeyBytes.concat(block);
  30. blockindex++;
  31. }
  32. // Truncate excess bytes
  33. derivedKeyBytes.length = keylen;
  34. return options && options.asBytes ? derivedKeyBytes :
  35. options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
  36. util.bytesToHex(derivedKeyBytes);
  37. };
  38. })();