evpkdf.js 3.9 KB

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