evpkdf.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. // Shortcut
  68. var cfg = this.cfg;
  69. // Init hasher
  70. var hasher = cfg.hasher.create();
  71. // Initial values
  72. var derivedKey = WordArray.create();
  73. // Shortcuts
  74. var derivedKeyWords = derivedKey.words;
  75. var keySize = cfg.keySize;
  76. var iterations = cfg.iterations;
  77. // Generate key
  78. while (derivedKeyWords.length < keySize) {
  79. if (block) {
  80. hasher.update(block);
  81. }
  82. var block = hasher.update(password).finalize(salt);
  83. hasher.reset();
  84. // Iterations
  85. for (var i = 1; i < iterations; i++) {
  86. block = hasher.finalize(block);
  87. hasher.reset();
  88. }
  89. derivedKey.concat(block);
  90. }
  91. derivedKey.sigBytes = keySize * 4;
  92. return derivedKey;
  93. }
  94. });
  95. /**
  96. * Derives a key from a password.
  97. *
  98. * @param {WordArray|string} password The password.
  99. * @param {WordArray|string} salt A salt.
  100. * @param {Object} cfg (Optional) The configuration options to use for this computation.
  101. *
  102. * @return {WordArray} The derived key.
  103. *
  104. * @static
  105. *
  106. * @example
  107. *
  108. * var key = CryptoJS.EvpKDF(password, salt);
  109. * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
  110. * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
  111. */
  112. C.EvpKDF = function (password, salt, cfg) {
  113. return EvpKDF.create(cfg).compute(password, salt);
  114. };
  115. }());
  116. return CryptoJS.EvpKDF;
  117. }));