浏览代码

refactor code

pull/342/head
Guillaume Vincent 8 年前
父节点
当前提交
f03a7d74e9
共有 5 个文件被更改,包括 1615 次插入285 次删除
  1. +13
    -117
      index.js
  2. +1472
    -162
      lib/lesspass.js
  3. +121
    -0
      src/v1.js
  4. +6
    -6
      src/v2.js
  5. +3
    -0
      tests/v2/api.tests.js

+ 13
- 117
index.js 查看文件

@@ -1,124 +1,20 @@
var pbkdf2 = require('pbkdf2');
var createHmac = require('create-hmac');
var Promise = require("bluebird");
var v1 = require('./src/v1');
var v2 = require('./src/v2');

module.exports = {
encryptLogin: _encryptLogin,
renderPassword: _renderPassword,
createFingerprint: createFingerprint,
_deriveEncryptedLogin: _deriveEncryptedLogin,
_getPasswordTemplate: _getPasswordTemplate,
_prettyPrint: _prettyPrint,
_string2charCodes: _string2charCodes,
_getCharType: _getCharType,
_getPasswordChar: _getPasswordChar,
_createHmac: _createHmac,
encryptLogin: v1.encryptLogin,
renderPassword: v1.renderPassword,
createFingerprint: v1.createFingerprint,
_deriveEncryptedLogin: v1._deriveEncryptedLogin,
_getPasswordTemplate: v1._getPasswordTemplate,
_prettyPrint: v1._prettyPrint,
_string2charCodes: v1._string2charCodes,
_getCharType: v1._getCharType,
_getPasswordChar: v1._getPasswordChar,
_createHmac: v1._createHmac,

generatePassword: v2.generatePassword,
_calcEntropy: v2._calcEntropy,
_getSetOfCharacters: v2._getSetOfCharacters,
_renderPassword: v2._renderPassword,
};

function _encryptLogin(login, masterPassword, options) {
var _options = options !== undefined ? options : {};
var iterations = _options.iterations || 8192;
var keylen = _options.keylen || 32;

return new Promise(function (resolve, reject) {
if (!login || !masterPassword) {
reject('login and master password parameters could not be empty');
}
pbkdf2.pbkdf2(masterPassword, login, iterations, keylen, 'sha256', function (error, key) {
if (error) {
reject('error in pbkdf2');
} else {
resolve(key.toString('hex'));
}
});
})
}

function _renderPassword(encryptedLogin, site, passwordOptions) {
return _deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) {
var template = passwordOptions.template || _getPasswordTemplate(passwordOptions);
return _prettyPrint(derivedEncryptedLogin, template);
});
}

function _createHmac(encryptedLogin, salt) {
return new Promise(function (resolve) {
resolve(createHmac('sha256', new Buffer(encryptedLogin)).update(salt).digest('hex'));
});
}

function _deriveEncryptedLogin(encryptedLogin, site, options) {
var _options = options !== undefined ? options : {};
var length = _options.length || 12;
var counter = _options.counter || 1;

var salt = site + counter.toString();
return _createHmac(encryptedLogin, salt).then(function (derivedHash) {
return derivedHash.substring(0, length);
});
}

function _getPasswordTemplate(passwordTypes) {
var templates = {
lowercase: 'vc',
uppercase: 'VC',
numbers: 'n',
symbols: 's',
};
var returnedTemplate = '';
Object.keys(templates).forEach(function (template) {
if (passwordTypes.hasOwnProperty(template) && passwordTypes[template]) {
returnedTemplate += templates[template]
}
});
return returnedTemplate;
}

function _prettyPrint(hash, template) {
var password = '';

_string2charCodes(hash).forEach(function (charCode, index) {
var charType = _getCharType(template, index);
password += _getPasswordChar(charType, charCode);
});
return password;
}

function _string2charCodes(text) {
var charCodes = [];
for (var i = 0; i < text.length; i++) {
charCodes.push(text.charCodeAt(i));
}
return charCodes;
}

function _getCharType(template, index) {
return template[index % template.length];
}

function _getPasswordChar(charType, index) {
var passwordsChars = {
V: 'AEIOUY',
C: 'BCDFGHJKLMNPQRSTVWXZ',
v: 'aeiouy',
c: 'bcdfghjklmnpqrstvwxz',
A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ',
a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz',
n: '0123456789',
s: '@&%?,=[]_:-+*$#!\'^~;()/.',
x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.'
};
var passwordChar = passwordsChars[charType];
return passwordChar[index % passwordChar.length];
}

function createFingerprint(str) {
return new Promise(function (resolve) {
resolve(createHmac('sha256', new Buffer(str)).digest('hex'))
});
}
};

+ 1472
- 162
lib/lesspass.js
文件差异内容过多而无法显示
查看文件


+ 121
- 0
src/v1.js 查看文件

@@ -0,0 +1,121 @@
var pbkdf2 = require('pbkdf2');
var createHMAC = require('create-hmac');
var Promise = require("bluebird");


module.exports = {
encryptLogin: encryptLogin,
renderPassword: renderPassword,
createFingerprint: createFingerprint,
_deriveEncryptedLogin: deriveEncryptedLogin,
_getPasswordTemplate: getPasswordTemplate,
_prettyPrint: prettyPrint,
_string2charCodes: string2charCodes,
_getCharType: getCharType,
_getPasswordChar: getPasswordChar,
_createHmac: createHmac,
};


function encryptLogin(login, masterPassword, options) {
var _options = options !== undefined ? options : {};
var iterations = _options.iterations || 8192;
var keylen = _options.keylen || 32;

return new Promise(function (resolve, reject) {
if (!login || !masterPassword) {
reject('login and master password parameters could not be empty');
}
pbkdf2.pbkdf2(masterPassword, login, iterations, keylen, 'sha256', function (error, key) {
if (error) {
reject('error in pbkdf2');
} else {
resolve(key.toString('hex'));
}
});
})
}

function renderPassword(encryptedLogin, site, passwordOptions) {
return deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) {
var template = passwordOptions.template || getPasswordTemplate(passwordOptions);
return prettyPrint(derivedEncryptedLogin, template);
});
}

function createHmac(encryptedLogin, salt) {
return new Promise(function (resolve) {
resolve(createHMAC('sha256', new Buffer(encryptedLogin)).update(salt).digest('hex'));
});
}

function deriveEncryptedLogin(encryptedLogin, site, options) {
var _options = options !== undefined ? options : {};
var length = _options.length || 12;
var counter = _options.counter || 1;

var salt = site + counter.toString();
return createHmac(encryptedLogin, salt).then(function (derivedHash) {
return derivedHash.substring(0, length);
});
}

function getPasswordTemplate(passwordTypes) {
var templates = {
lowercase: 'vc',
uppercase: 'VC',
numbers: 'n',
symbols: 's',
};
var returnedTemplate = '';
Object.keys(templates).forEach(function (template) {
if (passwordTypes.hasOwnProperty(template) && passwordTypes[template]) {
returnedTemplate += templates[template]
}
});
return returnedTemplate;
}

function prettyPrint(hash, template) {
var password = '';

string2charCodes(hash).forEach(function (charCode, index) {
var charType = getCharType(template, index);
password += getPasswordChar(charType, charCode);
});
return password;
}

function string2charCodes(text) {
var charCodes = [];
for (var i = 0; i < text.length; i++) {
charCodes.push(text.charCodeAt(i));
}
return charCodes;
}

function getCharType(template, index) {
return template[index % template.length];
}

function getPasswordChar(charType, index) {
var passwordsChars = {
V: 'AEIOUY',
C: 'BCDFGHJKLMNPQRSTVWXZ',
v: 'aeiouy',
c: 'bcdfghjklmnpqrstvwxz',
A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ',
a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz',
n: '0123456789',
s: '@&%?,=[]_:-+*$#!\'^~;()/.',
x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.'
};
var passwordChar = passwordsChars[charType];
return passwordChar[index % passwordChar.length];
}

function createFingerprint(str) {
return new Promise(function (resolve) {
resolve(createHMAC('sha256', new Buffer(str)).digest('hex'))
});
}

+ 6
- 6
src/v2.js 查看文件

@@ -2,7 +2,12 @@ var Promise = require("bluebird");
var pbkdf2 = require('pbkdf2');
var bigInt = require("big-integer");

exports.generatePassword = generatePassword;
module.exports = {
generatePassword: generatePassword,
_calcEntropy: calcEntropy,
_getSetOfCharacters: getSetOfCharacters,
_renderPassword: renderPassword
};

function generatePassword(site, login, masterPassword, passwordProfile) {
return calcEntropy(site, login, masterPassword, passwordProfile).then(function (entropy) {
@@ -11,11 +16,6 @@ function generatePassword(site, login, masterPassword, passwordProfile) {
});
}

exports._calcEntropy = calcEntropy;
exports._getSetOfCharacters = getSetOfCharacters;
exports._renderPassword = renderPassword;


function calcEntropy(site, login, masterPassword, passwordProfile) {
return new Promise(function (resolve, reject) {
var salt = site + login + passwordProfile.counter.toString(16);


+ 3
- 0
tests/v2/api.tests.js 查看文件

@@ -3,6 +3,7 @@ var assert = chai.assert;
describe('LessPass v2', function () {
describe('API', function () {
it('render password', function () {
this.timeout(10000);
var site = 'example.org';
var login = 'contact@example.org';
var masterPassword = 'password';
@@ -20,6 +21,7 @@ describe('LessPass v2', function () {
});
});
it('render password only digit', function () {
this.timeout(10000);
var site = 'example.org';
var login = 'contact@example.org';
var masterPassword = 'password';
@@ -37,6 +39,7 @@ describe('LessPass v2', function () {
});
});
it('render password no number', function () {
this.timeout(10000);
var site = 'example.org';
var login = 'contact@example.org';
var masterPassword = 'password';


正在加载...
取消
保存