From 36db5056a3e36a1dd8e8e2588a59b0d620ddbbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Mon, 17 Apr 2017 20:39:53 +0200 Subject: [PATCH] Add new encryption scheme in chrome addon/firefox webextension --- chrome_addon/compat.js | 1 + chrome_addon/lib/main.js | 128 ++++++++++++++++++++++++++------------ chrome_addon/lib/misc.js | 96 +++++++++++++++++++++------- chrome_addon/options.html | 3 + chrome_addon/options.js | 11 +++- 5 files changed, 178 insertions(+), 61 deletions(-) diff --git a/chrome_addon/compat.js b/chrome_addon/compat.js index 0abf3aa..58da9eb 100644 --- a/chrome_addon/compat.js +++ b/chrome_addon/compat.js @@ -19,6 +19,7 @@ function getPref(key) { + // Inspired from https://github.com/akiomik/chrome-storage-promise/ var promise = new Promise((resolve, reject) => { chrome.storage.local.get(key, (items) => { let err = chrome.runtime.lastError; diff --git a/chrome_addon/lib/main.js b/chrome_addon/lib/main.js index 27bfd9f..17253ec 100644 --- a/chrome_addon/lib/main.js +++ b/chrome_addon/lib/main.js @@ -18,7 +18,7 @@ */ var DEBUG = true; -var protocol_version = 3; +var protocol_version = 4; SERVER = {OK : 0, FAILED : 1, RESTART_REQUEST : 2}; @@ -47,14 +47,24 @@ function debug(s) console.log(s); } -function generate_request(domain, login, mkey) +async function generate_request(domain, login, mkey, iv, old) { - var v = "@@" + domain + ";" + login; - debug("will encrypt " + v); - //debug("with " + a2hex(mkey)); - enc = encrypt(mkey, v); - //debug("res " + a2hex(enc)); - + if (old) + { + var v = "@@" + domain + ";" + login; + debug("will encrypt " + v); + enc = encrypt_ecb(mkey, v); + } + else + { + var v = domain + ";" + login; + debug("will encrypt " + v); + while ((v.length % 16)) + v += "\0"; + hash = await digest(v); + v += hash.slice(8, 24); + enc = encrypt_cbc(mkey, iv, v); + } return enc; } @@ -68,23 +78,43 @@ async function ask_server(form, field, logins, domain, wdomain, mkey, submit) pbkdf2_level = await getPref("pbkdf2_level"); - mkey = pbkdf2(mkey, salt, pbkdf2_level); + global_iv = await simple_pbkdf2(salt, mkey, pbkdf2_level); + global_iv = global_iv.slice(0, 16); + mkey = crypto_pbkdf2(mkey, salt, pbkdf2_level); + debug("global_iv " + a2hex(global_iv)); + keys = ""; - for(a=0, b=logins.length; a 16) { - res = await _encrypt(mkey, data.slice(0, 16)); + res = await _encrypt(mkey, nulliv, data.slice(0, 16)); // Remove PKCS7 padding result += res.slice(0, 16); data = data.slice(16); } - res = await _encrypt(mkey, data); + res = await _encrypt(mkey, nulliv, data); result += res.slice(0, 16); return result; } -async function decrypt(mkey, data) +async function decrypt_ecb(mkey, data) { var result = ""; + nulliv = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + while (data.length > 16) { - res = await _decrypt(mkey, data.slice(0, 16)); + res = await _decrypt(mkey, nulliv, data.slice(0, 16)); // Remove PKCS7 padding result += res.slice(0, 16); data = data.slice(16); } - res = await _decrypt(mkey, data); + res = await _decrypt(mkey, nulliv, data); result += res.slice(0, 16); return result; } + +async function encrypt_cbc(mkey, iv, data) +{ + var result = await _encrypt(mkey, str2ab(iv), data); + + // Remove PKCS7 padding + return result.slice(0, result.length-16); +} + +async function decrypt_cbc(mkey, iv, data) +{ + var result = await _decrypt(mkey, str2ab(iv), data); + + // Remove PKCS7 padding + return result.slice(0, result.length-16); +} + +async function digest(data) +{ + return crypto.subtle.digest("SHA-256", str2ab(data)).then(function (hash) { + return ab2str(hash); + }); +} diff --git a/chrome_addon/options.html b/chrome_addon/options.html index e369a5f..07d56fd 100644 --- a/chrome_addon/options.html +++ b/chrome_addon/options.html @@ -10,6 +10,9 @@
PBKDF2 level Number of iterations used to derivate master key

+
+ Crypto v1 compatible Compatible with old crypto schema (AES ECB). Use it for encrypted passwords with server <= 0.7
+