hmac.js 3.9 KB

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