From 85ec5e33bc147d46639d8dec8bab4058a5ab0179 Mon Sep 17 00:00:00 2001 From: Gregory Soutade Date: Sat, 7 Dec 2013 10:14:38 +0100 Subject: [PATCH] Server side modifications Fix bad implementation of PKDBF2 and HMAC New protocol version (2) --- server/functions.php | 11 +++++------ server/ref/index.php | 2 +- server/ressources/gpass.js | 9 ++++++++- server/ressources/hmac.js | 20 ++++++++++++++------ server/ressources/jssha256.js | 13 ++++++++++++- server/ressources/pkdbf2.js | 22 +++++++--------------- 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/server/functions.php b/server/functions.php index df844d4..690050d 100755 --- a/server/functions.php +++ b/server/functions.php @@ -24,16 +24,11 @@ Password is salted (3 random characters) and encrypted - All is encrypted with AES256 and key : sha256(master key) + All is encrypted with AES256 and key : PKDBF2(hmac_sha256, master key, url, 1000) */ $MAX_ENTRY_LEN = 512; $USERS_PATH = "./users/"; -function get_mkey_hash($mkey) -{ - return bin2hex(hash("sha256", $mkey, true)); -} - function open_crypto($mkey) { if (!isset($_SESSION['td'])) @@ -191,6 +186,8 @@ function add_entry($user, $login, $password) $result = $db->query("INSERT INTO gpass ('login', 'password') VALUES ('" . $login . "', '" . $password . "')"); + $db->close(); + echo "OK"; return true; @@ -208,6 +205,8 @@ function delete_entry($user, $login) $db->query("DELETE FROM gpass WHERE login='" . $login . "'"); + $db->close(); + echo "OK"; return true; diff --git a/server/ref/index.php b/server/ref/index.php index 91c7c88..d750a21 100755 --- a/server/ref/index.php +++ b/server/ref/index.php @@ -31,7 +31,7 @@ function load_database() return $db; } -$PROTOCOL_VERSION = 1; +$PROTOCOL_VERSION = 2; $db = load_database(); diff --git a/server/ressources/gpass.js b/server/ressources/gpass.js index 2823770..c628e6c 100755 --- a/server/ressources/gpass.js +++ b/server/ressources/gpass.js @@ -81,6 +81,14 @@ function url_domain(data) { return uri['host']; } +// http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript +function hex2a(hex) { + var str = ''; + for (var i = 0; i < hex.length; i += 2) + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + return str; +} + function a2hex(str) { var hex = ''; for (var i = 0; i < str.length; i++) @@ -96,7 +104,6 @@ function derive_mkey(user, mkey) { url = url_domain(document.URL) + "/" + user; mkey = a2hex(pkdbf2(mkey, url, 1000, 256/8)); - return mkey; } diff --git a/server/ressources/hmac.js b/server/ressources/hmac.js index df3de30..e8af667 100644 --- a/server/ressources/hmac.js +++ b/server/ressources/hmac.js @@ -21,15 +21,23 @@ function hmac256(key, message) { var ipad = ""; var opad = ""; - for(i=0; i 512/8) { - ipad += String.fromCharCode(key.charCodeAt(i) ^ 0x36); - opad += String.fromCharCode(key.charCodeAt(i) ^ 0x5c); + key = digest256(key); } - while (ipad.length < 512/8) + + for(i=0; i<512/8; i++) { - ipad += String.fromCharCode(0x36); - opad += String.fromCharCode(0x5c); + if (i >= key.length) + { + ipad += String.fromCharCode(0x36); + opad += String.fromCharCode(0x5c); + } + else + { + ipad += String.fromCharCode(key.charCodeAt(i) ^ 0x36); + opad += String.fromCharCode(key.charCodeAt(i) ^ 0x5c); + } } result = digest256(opad + digest256(ipad + message)); diff --git a/server/ressources/jssha256.js b/server/ressources/jssha256.js index 840d22f..6d52f65 100644 --- a/server/ressources/jssha256.js +++ b/server/ressources/jssha256.js @@ -231,13 +231,24 @@ function sha256_encode_hex() { return output; } +/* Get the internal hash as string */ +function sha256_encode() { + var output = new String(); + for(var i=0; i<8; i++) { + for(var j=3; j>=0; j--) + output += String.fromCharCode((ihash[i] >>> j*8) & 0xff); + } + return output; +} + /* Main function: returns a hex string representing the SHA256 value of the given data */ function digest256 (data) { sha256_init(); sha256_update(data, data.length); sha256_final(); - return sha256_encode_hex(); + return sha256_encode(); + // return sha256_encode_hex(); } /* test if the JS-interpreter is working properly */ diff --git a/server/ressources/pkdbf2.js b/server/ressources/pkdbf2.js index 378dd5b..278c4d2 100644 --- a/server/ressources/pkdbf2.js +++ b/server/ressources/pkdbf2.js @@ -17,14 +17,6 @@ along with gPass. If not, see . */ -// http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript -function hex2a(hex) { - var str = ''; - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - return str; -} - function pkdbf2 (password, salt, iterations, outlen) { var result = ""; var temp = ""; @@ -34,17 +26,17 @@ function pkdbf2 (password, salt, iterations, outlen) { for (i=1; result.length < outlen; i++) { - temp = hex2a(hmac256(salt + - String.fromCharCode((i & 0xff000000) >> 24) + - String.fromCharCode((i & 0x00ff0000) >> 16) + - String.fromCharCode((i & 0x0000ff00) >> 8) + - String.fromCharCode((i & 0x000000ff) >> 0), - password)); + temp = hmac256(password, salt + + String.fromCharCode((i & 0xff000000) >> 24) + + String.fromCharCode((i & 0x00ff0000) >> 16) + + String.fromCharCode((i & 0x0000ff00) >> 8) + + String.fromCharCode((i & 0x000000ff) >> 0) + ); temp_res = temp; for(a=1; a