evpkdf.js 3.5 KB

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