browserHmac.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. var hashUtils = require('./browserHashUtils');
  2. /**
  3. * @api private
  4. */
  5. function Hmac(hashCtor, secret) {
  6. this.hash = new hashCtor();
  7. this.outer = new hashCtor();
  8. var inner = bufferFromSecret(hashCtor, secret);
  9. var outer = new Uint8Array(hashCtor.BLOCK_SIZE);
  10. outer.set(inner);
  11. for (var i = 0; i < hashCtor.BLOCK_SIZE; i++) {
  12. inner[i] ^= 0x36;
  13. outer[i] ^= 0x5c;
  14. }
  15. this.hash.update(inner);
  16. this.outer.update(outer);
  17. // Zero out the copied key buffer.
  18. for (var i = 0; i < inner.byteLength; i++) {
  19. inner[i] = 0;
  20. }
  21. }
  22. /**
  23. * @api private
  24. */
  25. module.exports = exports = Hmac;
  26. Hmac.prototype.update = function (toHash) {
  27. if (hashUtils.isEmptyData(toHash) || this.error) {
  28. return this;
  29. }
  30. try {
  31. this.hash.update(hashUtils.convertToBuffer(toHash));
  32. } catch (e) {
  33. this.error = e;
  34. }
  35. return this;
  36. };
  37. Hmac.prototype.digest = function (encoding) {
  38. if (!this.outer.finished) {
  39. this.outer.update(this.hash.digest());
  40. }
  41. return this.outer.digest(encoding);
  42. };
  43. function bufferFromSecret(hashCtor, secret) {
  44. var input = hashUtils.convertToBuffer(secret);
  45. if (input.byteLength > hashCtor.BLOCK_SIZE) {
  46. var bufferHash = new hashCtor;
  47. bufferHash.update(input);
  48. input = bufferHash.digest();
  49. }
  50. var buffer = new Uint8Array(hashCtor.BLOCK_SIZE);
  51. buffer.set(input);
  52. return buffer;
  53. }