evpkdf.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. ;(function (root, factory, undef) {
  2. if (typeof exports === "object") {
  3. // CommonJS
  4. module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac"));
  5. } else if (typeof define === "function" && define.amd) {
  6. // AMD
  7. define(["./core", "./sha1", "./hmac"], factory);
  8. } else {
  9. // Global (browser)
  10. factory(root.CryptoJS);
  11. }
  12. }(this, function (CryptoJS) {
  13. (function () {
  14. // Shortcuts
  15. var C = CryptoJS;
  16. var C_lib = C.lib;
  17. var Base = C_lib.Base;
  18. var WordArray = C_lib.WordArray;
  19. var C_algo = C.algo;
  20. var MD5 = C_algo.MD5;
  21. /**
  22. * This key derivation function is meant to conform with EVP_BytesToKey.
  23. * www.openssl.org/docs/crypto/EVP_BytesToKey.html
  24. */
  25. var EvpKDF = C_algo.EvpKDF = Base.extend({
  26. /**
  27. * Configuration options.
  28. *
  29. * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
  30. * @property {Hasher} hasher The hash algorithm to use. Default: MD5
  31. * @property {number} iterations The number of iterations to perform. Default: 1
  32. */
  33. cfg: Base.extend({
  34. keySize: 128 / 32,
  35. hasher: MD5,
  36. iterations: 1
  37. }),
  38. /**
  39. * Initializes a newly created key derivation function.
  40. *
  41. * @param {Object} cfg (Optional) The configuration options to use for the derivation.
  42. *
  43. * @example
  44. *
  45. * var kdf = CryptoJS.algo.EvpKDF.create();
  46. * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
  47. * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
  48. */
  49. init: function (cfg) {
  50. this.cfg = this.cfg.extend(cfg);
  51. },
  52. /**
  53. * Derives a key from a password.
  54. *
  55. * @param {WordArray|string} password The password.
  56. * @param {WordArray|string} salt A salt.
  57. *
  58. * @return {WordArray} The derived key.
  59. *
  60. * @example
  61. *
  62. * var key = kdf.compute(password, salt);
  63. */
  64. compute: function (password, salt) {
  65. // Shortcut
  66. var cfg = this.cfg;
  67. // Init hasher
  68. var hasher = cfg.hasher.create();
  69. // Initial values
  70. var derivedKey = WordArray.create();
  71. // Shortcuts
  72. var derivedKeyWords = derivedKey.words;
  73. var keySize = cfg.keySize;
  74. var iterations = cfg.iterations;
  75. // Generate key
  76. while (derivedKeyWords.length < keySize) {
  77. if (block) {
  78. hasher.update(block);
  79. }
  80. var block = hasher.update(password).finalize(salt);
  81. hasher.reset();
  82. // Iterations
  83. for (var i = 1; i < iterations; i++) {
  84. block = hasher.finalize(block);
  85. hasher.reset();
  86. }
  87. derivedKey.concat(block);
  88. }
  89. derivedKey.sigBytes = keySize * 4;
  90. return derivedKey;
  91. }
  92. });
  93. /**
  94. * Derives a key from a password.
  95. *
  96. * @param {WordArray|string} password The password.
  97. * @param {WordArray|string} salt A salt.
  98. * @param {Object} cfg (Optional) The configuration options to use for this computation.
  99. *
  100. * @return {WordArray} The derived key.
  101. *
  102. * @static
  103. *
  104. * @example
  105. *
  106. * var key = CryptoJS.EvpKDF(password, salt);
  107. * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
  108. * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
  109. */
  110. C.EvpKDF = function (password, salt, cfg) {
  111. return EvpKDF.create(cfg).compute(password, salt);
  112. };
  113. }());
  114. return CryptoJS.EvpKDF;
  115. }));