Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

105 linhas
3.1 KiB

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