You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

121 lines
3.8 KiB

  1. 'use strict';
  2. var pbkdf2 = require('pbkdf2');
  3. var createHmac = require('create-hmac');
  4. module.exports = {
  5. encryptLogin: _encryptLogin,
  6. renderPassword: _renderPassword,
  7. createFingerprint: createFingerprint,
  8. _deriveEncryptedLogin: _deriveEncryptedLogin,
  9. _getPasswordTemplate: _getPasswordTemplate,
  10. _prettyPrint: _prettyPrint,
  11. _string2charCodes: _string2charCodes,
  12. _getCharType: _getCharType,
  13. _getPasswordChar: _getPasswordChar,
  14. _createHmac: _createHmac
  15. };
  16. function _encryptLogin(login, masterPassword) {
  17. var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  18. var _ref$iterations = _ref.iterations;
  19. var iterations = _ref$iterations === undefined ? 8192 : _ref$iterations;
  20. var _ref$keylen = _ref.keylen;
  21. var keylen = _ref$keylen === undefined ? 32 : _ref$keylen;
  22. return new Promise(function (resolve, reject) {
  23. if (!login || !masterPassword) {
  24. reject('login and master password parameters could not be empty');
  25. }
  26. pbkdf2.pbkdf2(masterPassword, login, iterations, keylen, 'sha256', function (error, key) {
  27. if (error) {
  28. reject('error in pbkdf2');
  29. } else {
  30. resolve(key.toString('hex'));
  31. }
  32. });
  33. });
  34. }
  35. function _renderPassword(encryptedLogin, site, passwordOptions) {
  36. return _deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) {
  37. var template = passwordOptions.template || _getPasswordTemplate(passwordOptions);
  38. return _prettyPrint(derivedEncryptedLogin, template);
  39. });
  40. }
  41. function _createHmac(encryptedLogin, salt) {
  42. return new Promise(function (resolve) {
  43. resolve(createHmac('sha256', new Buffer(encryptedLogin)).update(salt).digest('hex'));
  44. });
  45. }
  46. function _deriveEncryptedLogin(encryptedLogin, site) {
  47. var passwordOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { length: 12, counter: 1 };
  48. var salt = site + passwordOptions.counter.toString();
  49. return _createHmac(encryptedLogin, salt).then(function (derivedHash) {
  50. return derivedHash.substring(0, passwordOptions.length);
  51. });
  52. }
  53. function _getPasswordTemplate(passwordTypes) {
  54. var templates = {
  55. lowercase: 'vc',
  56. uppercase: 'VC',
  57. numbers: 'n',
  58. symbols: 's'
  59. };
  60. var template = '';
  61. for (var templateKey in templates) {
  62. if (passwordTypes.hasOwnProperty(templateKey) && passwordTypes[templateKey]) {
  63. template += templates[templateKey];
  64. }
  65. }
  66. return template;
  67. }
  68. function _prettyPrint(hash, template) {
  69. var password = '';
  70. _string2charCodes(hash).forEach(function (charCode, index) {
  71. var charType = _getCharType(template, index);
  72. password += _getPasswordChar(charType, charCode);
  73. });
  74. return password;
  75. }
  76. function _string2charCodes(text) {
  77. var charCodes = [];
  78. for (var i = 0; i < text.length; i++) {
  79. charCodes.push(text.charCodeAt(i));
  80. }
  81. return charCodes;
  82. }
  83. function _getCharType(template, index) {
  84. return template[index % template.length];
  85. }
  86. function _getPasswordChar(charType, index) {
  87. var passwordsChars = {
  88. V: 'AEIOUY',
  89. C: 'BCDFGHJKLMNPQRSTVWXZ',
  90. v: 'aeiouy',
  91. c: 'bcdfghjklmnpqrstvwxz',
  92. A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ',
  93. a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz',
  94. n: '0123456789',
  95. s: '@&%?,=[]_:-+*$#!\'^~;()/.',
  96. x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.'
  97. };
  98. var passwordChar = passwordsChars[charType];
  99. return passwordChar[index % passwordChar.length];
  100. }
  101. function createFingerprint(str) {
  102. return new Promise(function (resolve) {
  103. resolve(createHmac('sha256', new Buffer(str)).digest('hex'));
  104. });
  105. }