Kaynağa Gözat

Use webcrypto only for browser

* prepare injection of encryption functions (https://github.com/lesspass/lesspass/issues/223)
 * reduce bundle size by 80%
pull/342/head
Guillaume Vincent 7 yıl önce
ebeveyn
işleme
c77b44e93c
8 değiştirilmiş dosya ile 119 ekleme ve 68 silme
  1. +8
    -5
      package.json
  2. +31
    -0
      src/hmac.browser.js
  3. +9
    -0
      src/hmac.js
  4. +2
    -6
      src/lesspass.js
  5. +42
    -0
      src/pbkdf2.browser.js
  6. +4
    -51
      src/pbkdf2.js
  7. +2
    -6
      src/v1.js
  8. +21
    -0
      test/hmac.tests.js

+ 8
- 5
package.json Dosyayı Görüntüle

@@ -1,6 +1,6 @@
{
"name": "lesspass",
"version": "6.1.0",
"version": "7.0.0",
"description": "LessPass node module used to generate LessPass passwords",
"keywords": [
"crypto",
@@ -13,8 +13,13 @@
"dist",
"src"
],
"main": "dist/lesspass.min.js",
"main": "src/lesspass.js",
"browser": {
"./src/pbkdf2.js": "./src/pbkdf2.browser.js",
"./src/hmac.js": "./src/hmac.browser.js"
},
"module": "src/lesspass.js",
"jsnext:main": "src/lesspass.js",
"repository": "lesspass/core",
"scripts": {
"precommit": "npm test && lint-staged",
@@ -27,11 +32,9 @@
},
"dependencies": {
"big-integer": "^1.6.22",
"buffer": "^5.0.6",
"create-hmac": "^1.1.4",
"es6-promise": "^4.1.0",
"lodash.assign": "^4.2.0",
"pbkdf2": "^3.0.9"
"unibabel": "^2.1.4"
},
"devDependencies": {
"browserify": "^14.3.0",


+ 31
- 0
src/hmac.browser.js Dosyayı Görüntüle

@@ -0,0 +1,31 @@
require("unibabel");
require("unibabel/unibabel.hex");

module.exports = function(digest, string, salt) {
var algorithms = {
sha1: "SHA-1",
"sha-1": "SHA-1",
sha256: "SHA-256",
"sha-256": "SHA-256",
sha512: "SHA-512",
"sha-512": "SHA-512"
};
return window.crypto.subtle
.importKey(
"raw",
Unibabel.utf8ToBuffer(string),
{
name: "HMAC",
hash: { name: algorithms[digest.toLowerCase()] }
},
true,
["sign", "verify"]
)
.then(function(key) {
return window.crypto.subtle
.sign({ name: "HMAC" }, key, Unibabel.utf8ToBuffer(salt || ""))
.then(function(signature) {
return Unibabel.bufferToHex(new Uint8Array(signature));
});
});
};

+ 9
- 0
src/hmac.js Dosyayı Görüntüle

@@ -0,0 +1,9 @@
var crypto = require("crypto");
var Promise = require("es6-promise").Promise;

module.exports = function(digest, string, salt) {
return new Promise(function(resolve) {
var hmac = crypto.createHmac(digest, string);
resolve(hmac.update(salt || "").digest("hex"));
});
};

+ 2
- 6
src/lesspass.js Dosyayı Görüntüle

@@ -1,8 +1,6 @@
var v1 = require("./v1");
var v2 = require("./v2");
var createHMAC = require("create-hmac");
var Buffer = require("buffer/").Buffer;
var Promise = require("es6-promise").Promise;
var hmac = require("./hmac");

module.exports = {
generatePassword: function(site, login, masterPassword, options) {
@@ -12,8 +10,6 @@ module.exports = {
return v2.generatePassword(site, login, masterPassword, options);
},
createFingerprint: function(str) {
return new Promise(function(resolve) {
resolve(createHMAC("sha256", new Buffer(str)).digest("hex"));
});
return hmac("sha256", str);
}
};

+ 42
- 0
src/pbkdf2.browser.js Dosyayı Görüntüle

@@ -0,0 +1,42 @@
require("unibabel");
require("unibabel/unibabel.hex");

module.exports = function(password, salt, iterations, keylen, digest) {
var algorithms = {
sha1: "SHA-1",
"sha-1": "SHA-1",
sha256: "SHA-256",
"sha-256": "SHA-256",
sha512: "SHA-512",
"sha-512": "SHA-512"
};
return window.crypto.subtle
.importKey("raw", Unibabel.utf8ToBuffer(password), "PBKDF2", false, [
"deriveKey"
])
.then(function(key) {
var algo = {
name: "PBKDF2",
salt: Unibabel.utf8ToBuffer(salt),
iterations: iterations,
hash: algorithms[digest.toLowerCase()]
};
return window.crypto.subtle.deriveKey(
algo,
key,
{
name: "AES-CTR",
length: keylen * 8
},
true,
["encrypt", "decrypt"]
);
})
.then(function(derivedKey) {
return window.crypto.subtle
.exportKey("raw", derivedKey)
.then(function(keyArray) {
return Unibabel.bufferToHex(new Uint8Array(keyArray));
});
});
};

+ 4
- 51
src/pbkdf2.js Dosyayı Görüntüle

@@ -1,54 +1,9 @@
var pbkdf2 = require("pbkdf2");
var Buffer = require("buffer/").Buffer;
const crypto = require("crypto");
var Promise = require("es6-promise").Promise;

function shouldUseNative() {
return !!(typeof window !== "undefined" &&
window.crypto &&
window.crypto.subtle);
}

function pbkdf2WebCrypto(password, salt, iterations, keylen, digest) {
var algorithms = {
sha1: "SHA-1",
"sha-1": "SHA-1",
sha256: "SHA-256",
"sha-256": "SHA-256",
sha512: "SHA-512",
"sha-512": "SHA-512"
};
return window.crypto.subtle
.importKey("raw", new Buffer(password), "PBKDF2", false, ["deriveKey"])
.then(function(key) {
var algo = {
name: "PBKDF2",
salt: new Buffer(salt),
iterations: iterations,
hash: algorithms[digest.toLowerCase()]
};
return window.crypto.subtle.deriveKey(
algo,
key,
{
name: "AES-CTR",
length: keylen * 8
},
true,
["encrypt", "decrypt"]
);
})
.then(function(derivedKey) {
return window.crypto.subtle
.exportKey("raw", derivedKey)
.then(function(keyArray) {
return new Buffer(keyArray).toString("hex");
});
});
}

function pbkdf2Browserified(password, salt, iterations, keylen, digest) {
module.exports = function(password, salt, iterations, keylen, digest) {
return new Promise(function(resolve, reject) {
pbkdf2.pbkdf2(password, salt, iterations, keylen, digest, function(
crypto.pbkdf2(password, salt, iterations, keylen, digest, function(
error,
key
) {
@@ -59,6 +14,4 @@ function pbkdf2Browserified(password, salt, iterations, keylen, digest) {
}
});
});
}

module.exports = shouldUseNative() ? pbkdf2WebCrypto : pbkdf2Browserified;
};

+ 2
- 6
src/v1.js Dosyayı Görüntüle

@@ -1,6 +1,6 @@
var pbkdf2 = require("./pbkdf2");
var assign = require("lodash.assign");
var createHMAC = require("create-hmac");
var hmac = require("./hmac");

module.exports = {
generatePassword: generatePassword,
@@ -58,11 +58,7 @@ function renderPassword(encryptedLogin, site, passwordOptions) {

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



+ 21
- 0
test/hmac.tests.js Dosyayı Görüntüle

@@ -0,0 +1,21 @@
var assert = require("assert");
var createHmac = require("../src/hmac");

describe("hmac", function() {
it("createHmac", function() {
return createHmac("sha256", "password").then(function(fingerprint) {
assert.equal(
"e56a207acd1e6714735487c199c6f095844b7cc8e5971d86c003a7b6f36ef51e",
fingerprint
);
});
});
it("createHmac and update", function() {
return createHmac("sha256", "password", "salt").then(function(fingerprint) {
assert.equal(
"fc328232993ff34ca56631e4a101d60393cad12171997ee0b562bf7852b2fed0",
fingerprint
);
});
});
});

Yükleniyor…
İptal
Kaydet