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.

index.js 3.9 KiB

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