sync.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. var sizes = {
  3. __proto__: null,
  4. md5: 16,
  5. sha1: 20,
  6. sha224: 28,
  7. sha256: 32,
  8. sha384: 48,
  9. sha512: 64,
  10. 'sha512-256': 32,
  11. rmd160: 20,
  12. ripemd160: 20
  13. };
  14. var mapping = {
  15. __proto__: null,
  16. 'sha-1': 'sha1',
  17. 'sha-224': 'sha224',
  18. 'sha-256': 'sha256',
  19. 'sha-384': 'sha384',
  20. 'sha-512': 'sha512',
  21. 'ripemd-160': 'ripemd160'
  22. };
  23. var createHmac = require('create-hmac');
  24. var Buffer = require('safe-buffer').Buffer;
  25. var checkParameters = require('./precondition');
  26. var defaultEncoding = require('./default-encoding');
  27. var toBuffer = require('./to-buffer');
  28. function pbkdf2(password, salt, iterations, keylen, digest) {
  29. checkParameters(iterations, keylen);
  30. password = toBuffer(password, defaultEncoding, 'Password');
  31. salt = toBuffer(salt, defaultEncoding, 'Salt');
  32. var lowerDigest = (digest || 'sha1').toLowerCase();
  33. var mappedDigest = mapping[lowerDigest] || lowerDigest;
  34. var size = sizes[mappedDigest];
  35. if (typeof size !== 'number' || !size) {
  36. throw new TypeError('Digest algorithm not supported: ' + digest);
  37. }
  38. var DK = Buffer.allocUnsafe(keylen);
  39. var block1 = Buffer.allocUnsafe(salt.length + 4);
  40. salt.copy(block1, 0, 0, salt.length);
  41. var destPos = 0;
  42. var hLen = size;
  43. var l = Math.ceil(keylen / hLen);
  44. for (var i = 1; i <= l; i++) {
  45. block1.writeUInt32BE(i, salt.length);
  46. var T = createHmac(mappedDigest, password).update(block1).digest();
  47. var U = T;
  48. for (var j = 1; j < iterations; j++) {
  49. U = createHmac(mappedDigest, password).update(U).digest();
  50. for (var k = 0; k < hLen; k++) {
  51. T[k] ^= U[k];
  52. }
  53. }
  54. T.copy(DK, destPos);
  55. destPos += hLen;
  56. }
  57. return DK;
  58. }
  59. module.exports = pbkdf2;