auth.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* jslint node: true */
  2. 'use strict';
  3. var binding = require('../build/Release/sodium');
  4. var AuthKey = require('./keys/auth-key');
  5. var toBuffer = require('./toBuffer');
  6. var assert = require('assert');
  7. /**
  8. * Message Authentication
  9. *
  10. * Security model
  11. *
  12. * The crypto_auth function, viewed as a function of the message for a uniform
  13. * random key, is designed to meet the standard notion of unforgeability. This
  14. * means that an attacker cannot find authenticators for any messages not
  15. * authenticated by the sender, even if the attacker has adaptively influenced
  16. * the messages authenticated by the sender. For a formal definition see,
  17. * e.g., Section 2.4 of Bellare, Kilian, and Rogaway, "The security of the
  18. * cipher block chaining message authentication code," Journal of Computer and
  19. * System Sciences 61 (2000), 362–399;
  20. * http://www-cse.ucsd.edu/~mihir/papers/cbc.html.
  21. *
  22. * NaCl does not make any promises regarding "strong" unforgeability; perhaps
  23. * one valid authenticator can be converted into another valid authenticator
  24. * for the same message.
  25. * NaCl also does not make any promises regarding "truncated unforgeability."
  26. *
  27. * The secretKey *MUST* remain secret or an attacker could forge valid
  28. * authenticator tokens
  29. *
  30. * If key is not given a new random key is generated
  31. *
  32. * @param {String|Buffer|Array} [secretKey] A valid auth secret key
  33. * @constructor
  34. */
  35. module.exports = function Auth(secretKey, encoding) {
  36. var self = this;
  37. /** default encoding to use in all string operations */
  38. self.defaultEncoding = undefined;
  39. // Init key
  40. self.secretKey = new AuthKey(secretKey, encoding);
  41. /** Size of the authentication token */
  42. self.bytes = function () {
  43. return binding.crypto_auth_BYTES;
  44. };
  45. /** String name of the default crypto primitive used in auth operations */
  46. self.primitive = function() {
  47. return binding.crypto_auth_PRIMITIVE;
  48. };
  49. /**
  50. * Get the auth-key secret key object
  51. * @returns {AuthKey|*}
  52. */
  53. self.key = function() {
  54. return self.secretKey;
  55. };
  56. /**
  57. * Set the default encoding to use in all string conversions
  58. * @param {String} encoding encoding to use
  59. */
  60. self.setEncoding = function(encoding) {
  61. assert(!!encoding.match(/^(?:utf8|ascii|binary|hex|utf16le|ucs2|base64)$/), 'Encoding ' + encoding + ' is currently unsupported.');
  62. self.defaultEncoding = encoding;
  63. };
  64. /**
  65. * Get the current default encoding
  66. * @returns {undefined|String}
  67. */
  68. self.getEncoding = function() {
  69. return self.defaultEncoding;
  70. };
  71. /**
  72. * Generate authentication token for message, based on the secret key
  73. *
  74. * @param {string|Buffer|Array} message message to authenticate
  75. * @param {String} [encoding ] If v is a string you can specify the encoding
  76. */
  77. self.generate = function(message, encoding) {
  78. encoding = encoding || self.defaultEncoding;
  79. var messageBuf = toBuffer(message, encoding);
  80. return binding.crypto_auth(messageBuf, self.secretKey.get());
  81. };
  82. /**
  83. * Checks if the token authenticates the message
  84. *
  85. * @param {String|Buffer|Array} token message token
  86. * @param {String|Buffer|Array} message message to authenticate
  87. * @param {String} [encoding] If v is a string you can specify the encoding
  88. */
  89. self.validate = function(token, message, encoding) {
  90. if(!self.secretKey) {
  91. throw new Error('Auth: no secret key found');
  92. }
  93. encoding = encoding || self.defaultEncoding;
  94. var tokenBuf = toBuffer(token, encoding);
  95. var messageBuf = toBuffer(message, encoding);
  96. return binding.crypto_auth_verify(tokenBuf, messageBuf, self.secretKey.get()) ? false : true;
  97. };
  98. };