fernet.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. var CryptoJS = require('crypto-js/core');
  2. var AES = require('crypto-js/aes');
  3. var Utf8 = require('crypto-js/enc-utf8');
  4. var Latin1 = require('crypto-js/enc-latin1');
  5. var Hex = require('crypto-js/enc-hex');
  6. var Base64 = require('crypto-js/enc-base64');
  7. var HmacSHA256 = require('crypto-js/hmac-sha256');
  8. var URLBase64 = require('urlsafe-base64');
  9. var crypto = require('crypto');
  10. //lpad a string for some hex conversions
  11. String.prototype.lpad = function (padString, length) {
  12. var str = this;
  13. while (str.length < length) str = padString + str;
  14. return str;
  15. }
  16. //Makes a Base64 string a url-safe base64 string
  17. var urlsafe = function urlsafe(string) {
  18. return string.replace(/\+/g, '-').replace(/\//g, '_') //.replace(/=+$/, '')
  19. }
  20. // parse a Hex string to an Int
  21. var parseHex = function parseHex(hexString) {
  22. return parseInt('0x' + hexString);
  23. }
  24. // turn bits into number of chars in a hex string
  25. var hexBits = function hexBits(bits) {
  26. return bits / 8 * 2;
  27. }
  28. // convert base64 string to hex string
  29. var decode64toHex = function decode64(string) {
  30. var s = URLBase64.decode(string.replace(/=+$/, ''));
  31. return (new Buffer(s)).toString('hex');
  32. }
  33. // convert array to hex string
  34. var ArrayToHex = function ArrayToHex(array) {
  35. var hex = '';
  36. for (var _byte in array) {
  37. hex += Number(_byte).toString(16).lpad('0', 2);
  38. }
  39. return hex;
  40. }
  41. var randomHex = function (size) {
  42. return crypto.randomBytes(128 / 8).toString('hex')
  43. }
  44. var setIV = function setIV(iv_array) {
  45. if (iv_array) {
  46. this.ivHex = ArrayToHex(iv_array);
  47. } else {
  48. this.ivHex = randomHex(128 / 8);
  49. }
  50. this.iv = Hex.parse(this.ivHex);
  51. return this.ivHex;
  52. }
  53. //convert Time object or now into WordArray
  54. var timeBytes = function timeBytes(time) {
  55. if (time) {
  56. time = (time / 1000)
  57. } else {
  58. time = (Math.round(new Date() / 1000))
  59. }
  60. var hexTime = time.toString(16).lpad('0', '16')
  61. return Hex.parse(hexTime);
  62. }
  63. var fernet = function fernet(opts) {
  64. this.Hex = Hex;
  65. this.Base64 = Base64;
  66. this.parseHex = parseHex;
  67. this.decode64toHex = decode64toHex;
  68. this.hexBits = hexBits;
  69. this.urlsafe = urlsafe;
  70. //Sets the secret from base64 encoded value
  71. this.setSecret = function setSecret(secret64) {
  72. this.secret = new this.Secret(secret64);
  73. return this.secret;
  74. }
  75. this.ArrayToHex = ArrayToHex;
  76. this.setIV = setIV;
  77. this.encryptMessage = function (message, encryptionKey, iv) {
  78. var encrypted = AES.encrypt(message, encryptionKey, { iv: iv });
  79. return encrypted.ciphertext;
  80. }
  81. this.decryptMessage = function (cipherText, encryptionKey, iv) {
  82. var encrypted = {};
  83. encrypted.key = encryptionKey;
  84. encrypted.iv = iv;
  85. encrypted.ciphertext = cipherText;
  86. var decrypted = AES.decrypt(encrypted, encryptionKey, { iv: iv });
  87. return decrypted.toString(Utf8);
  88. }
  89. this.timeBytes = timeBytes;
  90. this.createToken = function (signingKey, time, iv, cipherText) {
  91. var hmac = this.createHmac(signingKey, time, iv, cipherText);
  92. var tokenWords = Hex.parse(this.versionHex);
  93. tokenWords = tokenWords.concat(time);
  94. tokenWords = tokenWords.concat(iv);
  95. tokenWords = tokenWords.concat(cipherText);
  96. tokenWords = tokenWords.concat(hmac);
  97. return urlsafe(tokenWords.toString(Base64));
  98. }
  99. this.createHmac = function createHmac(signingKey, time, iv, cipherText) {
  100. var hmacWords = Hex.parse(this.versionHex);
  101. hmacWords = hmacWords.concat(time);
  102. hmacWords = hmacWords.concat(iv);
  103. hmacWords = hmacWords.concat(cipherText);
  104. return HmacSHA256(hmacWords, signingKey);
  105. }
  106. this.Secret = require('./lib/secret');
  107. this.Token = require('./lib/token')(this);
  108. opts = opts || {};
  109. this.ttl = opts.ttl || 60;
  110. // because (0 || x) always equals x
  111. if (opts.ttl === 0) this.ttl = 0;
  112. this.versionHex = '80';
  113. this.setIV(opts.iv);
  114. if (opts.secret) { this.setSecret(opts.secret) }
  115. }
  116. exports = module.exports = fernet;
  117. fernet.call(exports)