hmac.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ;(function (root, factory) {
  2. if (typeof exports === "object") {
  3. // CommonJS
  4. module.exports = exports = factory(require("./core"));
  5. } else if (typeof define === "function" && define.amd) {
  6. // AMD
  7. define(["./core"], 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 C_enc = C.enc;
  19. var Utf8 = C_enc.Utf8;
  20. var C_algo = C.algo;
  21. /**
  22. * HMAC algorithm.
  23. */
  24. var HMAC = C_algo.HMAC = Base.extend({
  25. /**
  26. * Initializes a newly created HMAC.
  27. *
  28. * @param {Hasher} hasher The hash algorithm to use.
  29. * @param {WordArray|string} key The secret key.
  30. *
  31. * @example
  32. *
  33. * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
  34. */
  35. init: function (hasher, key) {
  36. // Init hasher
  37. hasher = this._hasher = new hasher.init();
  38. // Convert string to WordArray, else assume WordArray already
  39. if (typeof key == 'string') {
  40. key = Utf8.parse(key);
  41. }
  42. // Shortcuts
  43. var hasherBlockSize = hasher.blockSize;
  44. var hasherBlockSizeBytes = hasherBlockSize * 4;
  45. // Allow arbitrary length keys
  46. if (key.sigBytes > hasherBlockSizeBytes) {
  47. key = hasher.finalize(key);
  48. }
  49. // Clamp excess bits
  50. key.clamp();
  51. // Clone key for inner and outer pads
  52. var oKey = this._oKey = key.clone();
  53. var iKey = this._iKey = key.clone();
  54. // Shortcuts
  55. var oKeyWords = oKey.words;
  56. var iKeyWords = iKey.words;
  57. // XOR keys with pad constants
  58. for (var i = 0; i < hasherBlockSize; i++) {
  59. oKeyWords[i] ^= 0x5c5c5c5c;
  60. iKeyWords[i] ^= 0x36363636;
  61. }
  62. oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
  63. // Set initial values
  64. this.reset();
  65. },
  66. /**
  67. * Resets this HMAC to its initial state.
  68. *
  69. * @example
  70. *
  71. * hmacHasher.reset();
  72. */
  73. reset: function () {
  74. // Shortcut
  75. var hasher = this._hasher;
  76. // Reset
  77. hasher.reset();
  78. hasher.update(this._iKey);
  79. },
  80. /**
  81. * Updates this HMAC with a message.
  82. *
  83. * @param {WordArray|string} messageUpdate The message to append.
  84. *
  85. * @return {HMAC} This HMAC instance.
  86. *
  87. * @example
  88. *
  89. * hmacHasher.update('message');
  90. * hmacHasher.update(wordArray);
  91. */
  92. update: function (messageUpdate) {
  93. this._hasher.update(messageUpdate);
  94. // Chainable
  95. return this;
  96. },
  97. /**
  98. * Finalizes the HMAC computation.
  99. * Note that the finalize operation is effectively a destructive, read-once operation.
  100. *
  101. * @param {WordArray|string} messageUpdate (Optional) A final message update.
  102. *
  103. * @return {WordArray} The HMAC.
  104. *
  105. * @example
  106. *
  107. * var hmac = hmacHasher.finalize();
  108. * var hmac = hmacHasher.finalize('message');
  109. * var hmac = hmacHasher.finalize(wordArray);
  110. */
  111. finalize: function (messageUpdate) {
  112. // Shortcut
  113. var hasher = this._hasher;
  114. // Compute HMAC
  115. var innerHash = hasher.finalize(messageUpdate);
  116. hasher.reset();
  117. var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
  118. return hmac;
  119. }
  120. });
  121. }());
  122. }));