crypto.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Load modules
  2. var Crypto = require('crypto');
  3. var Url = require('url');
  4. var Utils = require('./utils');
  5. // Declare internals
  6. var internals = {};
  7. // MAC normalization format version
  8. exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats
  9. // Supported HMAC algorithms
  10. exports.algorithms = ['sha1', 'sha256'];
  11. // Calculate the request MAC
  12. /*
  13. type: 'header', // 'header', 'bewit', 'response'
  14. credentials: {
  15. key: 'aoijedoaijsdlaksjdl',
  16. algorithm: 'sha256' // 'sha1', 'sha256'
  17. },
  18. options: {
  19. method: 'GET',
  20. resource: '/resource?a=1&b=2',
  21. host: 'example.com',
  22. port: 8080,
  23. ts: 1357718381034,
  24. nonce: 'd3d345f',
  25. hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=',
  26. ext: 'app-specific-data',
  27. app: 'hf48hd83qwkj', // Application id (Oz)
  28. dlg: 'd8djwekds9cj' // Delegated by application id (Oz), requires options.app
  29. }
  30. */
  31. exports.calculateMac = function (type, credentials, options) {
  32. var normalized = exports.generateNormalizedString(type, options);
  33. var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized);
  34. var digest = hmac.digest('base64');
  35. return digest;
  36. };
  37. exports.generateNormalizedString = function (type, options) {
  38. var resource = options.resource || '';
  39. if (resource &&
  40. resource[0] !== '/') {
  41. var url = Url.parse(resource, false);
  42. resource = url.path; // Includes query
  43. }
  44. var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
  45. options.ts + '\n' +
  46. options.nonce + '\n' +
  47. (options.method || '').toUpperCase() + '\n' +
  48. resource + '\n' +
  49. options.host.toLowerCase() + '\n' +
  50. options.port + '\n' +
  51. (options.hash || '') + '\n';
  52. if (options.ext) {
  53. normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
  54. }
  55. normalized += '\n';
  56. if (options.app) {
  57. normalized += options.app + '\n' +
  58. (options.dlg || '') + '\n';
  59. }
  60. return normalized;
  61. };
  62. exports.calculatePayloadHash = function (payload, algorithm, contentType) {
  63. var hash = exports.initializePayloadHash(algorithm, contentType);
  64. hash.update(payload || '');
  65. return exports.finalizePayloadHash(hash);
  66. };
  67. exports.initializePayloadHash = function (algorithm, contentType) {
  68. var hash = Crypto.createHash(algorithm);
  69. hash.update('hawk.' + exports.headerVersion + '.payload\n');
  70. hash.update(Utils.parseContentType(contentType) + '\n');
  71. return hash;
  72. };
  73. exports.finalizePayloadHash = function (hash) {
  74. hash.update('\n');
  75. return hash.digest('base64');
  76. };
  77. exports.calculateTsMac = function (ts, credentials) {
  78. var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
  79. hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
  80. return hmac.digest('base64');
  81. };
  82. exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
  83. var now = Utils.nowSecs(localtimeOffsetMsec);
  84. var tsm = exports.calculateTsMac(now, credentials);
  85. return { ts: now, tsm: tsm };
  86. };