crypto.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
  39. options.ts + '\n' +
  40. options.nonce + '\n' +
  41. (options.method || '').toUpperCase() + '\n' +
  42. (options.resource || '') + '\n' +
  43. options.host.toLowerCase() + '\n' +
  44. options.port + '\n' +
  45. (options.hash || '') + '\n';
  46. if (options.ext) {
  47. normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
  48. }
  49. normalized += '\n';
  50. if (options.app) {
  51. normalized += options.app + '\n' +
  52. (options.dlg || '') + '\n';
  53. }
  54. return normalized;
  55. };
  56. exports.calculatePayloadHash = function (payload, algorithm, contentType) {
  57. var hash = exports.initializePayloadHash(algorithm, contentType);
  58. hash.update(payload || '');
  59. return exports.finalizePayloadHash(hash);
  60. };
  61. exports.initializePayloadHash = function (algorithm, contentType) {
  62. var hash = Crypto.createHash(algorithm);
  63. hash.update('hawk.' + exports.headerVersion + '.payload\n');
  64. hash.update(Utils.parseContentType(contentType) + '\n');
  65. return hash;
  66. };
  67. exports.finalizePayloadHash = function (hash) {
  68. hash.update('\n');
  69. return hash.digest('base64');
  70. };
  71. exports.calculateTsMac = function (ts, credentials) {
  72. var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
  73. hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
  74. return hmac.digest('base64');
  75. };
  76. exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
  77. var now = Math.floor((Utils.now() + (localtimeOffsetMsec || 0)) / 1000);
  78. var tsm = exports.calculateTsMac(now, credentials);
  79. return { ts: now, tsm: tsm };
  80. };