index.js 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. 'use strict';
  2. // Implements Brad Hill's Double HMAC pattern from
  3. // https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/.
  4. // The approach is similar to the node's native implementation of timing safe buffer comparison that will be available on v6+.
  5. // https://github.com/nodejs/node/issues/3043
  6. // https://github.com/nodejs/node/pull/3073
  7. var crypto = require('crypto');
  8. function bufferEqual(a, b) {
  9. if (a.length !== b.length) {
  10. return false;
  11. }
  12. // `crypto.timingSafeEqual` was introduced in Node v6.6.0
  13. // <https://github.com/jshttp/basic-auth/issues/39>
  14. if (crypto.timingSafeEqual) {
  15. return crypto.timingSafeEqual(a, b);
  16. }
  17. for (var i = 0; i < a.length; i++) {
  18. if (a[i] !== b[i]) {
  19. return false;
  20. }
  21. }
  22. return true;
  23. }
  24. function timeSafeCompare(a, b) {
  25. var sa = String(a);
  26. var sb = String(b);
  27. var key = crypto.pseudoRandomBytes(32);
  28. var ah = crypto.createHmac('sha256', key).update(sa).digest();
  29. var bh = crypto.createHmac('sha256', key).update(sb).digest();
  30. return bufferEqual(ah, bh) && a === b;
  31. }
  32. module.exports = timeSafeCompare;