Server side modifications

Fix bad implementation of PKDBF2 and HMAC
New protocol version (2)
This commit is contained in:
Gregory Soutade 2013-12-07 10:14:38 +01:00
parent 86877d86e7
commit 85ec5e33bc
6 changed files with 47 additions and 30 deletions

View File

@ -24,16 +24,11 @@
Password is salted (3 random characters) and encrypted 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; $MAX_ENTRY_LEN = 512;
$USERS_PATH = "./users/"; $USERS_PATH = "./users/";
function get_mkey_hash($mkey)
{
return bin2hex(hash("sha256", $mkey, true));
}
function open_crypto($mkey) function open_crypto($mkey)
{ {
if (!isset($_SESSION['td'])) 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 . "')"); $result = $db->query("INSERT INTO gpass ('login', 'password') VALUES ('" . $login . "', '" . $password . "')");
$db->close();
echo "OK"; echo "OK";
return true; return true;
@ -208,6 +205,8 @@ function delete_entry($user, $login)
$db->query("DELETE FROM gpass WHERE login='" . $login . "'"); $db->query("DELETE FROM gpass WHERE login='" . $login . "'");
$db->close();
echo "OK"; echo "OK";
return true; return true;

View File

@ -31,7 +31,7 @@ function load_database()
return $db; return $db;
} }
$PROTOCOL_VERSION = 1; $PROTOCOL_VERSION = 2;
$db = load_database(); $db = load_database();

View File

@ -81,6 +81,14 @@ function url_domain(data) {
return uri['host']; 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) { function a2hex(str) {
var hex = ''; var hex = '';
for (var i = 0; i < str.length; i++) for (var i = 0; i < str.length; i++)
@ -96,7 +104,6 @@ function derive_mkey(user, mkey)
{ {
url = url_domain(document.URL) + "/" + user; url = url_domain(document.URL) + "/" + user;
mkey = a2hex(pkdbf2(mkey, url, 1000, 256/8)); mkey = a2hex(pkdbf2(mkey, url, 1000, 256/8));
return mkey; return mkey;
} }

View File

@ -21,15 +21,23 @@ function hmac256(key, message) {
var ipad = ""; var ipad = "";
var opad = ""; var opad = "";
for(i=0; i<key.length; i++) if (key.length > 512/8)
{ {
ipad += String.fromCharCode(key.charCodeAt(i) ^ 0x36); key = digest256(key);
opad += String.fromCharCode(key.charCodeAt(i) ^ 0x5c);
} }
while (ipad.length < 512/8)
for(i=0; i<512/8; i++)
{ {
ipad += String.fromCharCode(0x36); if (i >= key.length)
opad += String.fromCharCode(0x5c); {
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)); result = digest256(opad + digest256(ipad + message));

View File

@ -231,13 +231,24 @@ function sha256_encode_hex() {
return output; 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 /* Main function: returns a hex string representing the SHA256 value of the
given data */ given data */
function digest256 (data) { function digest256 (data) {
sha256_init(); sha256_init();
sha256_update(data, data.length); sha256_update(data, data.length);
sha256_final(); sha256_final();
return sha256_encode_hex(); return sha256_encode();
// return sha256_encode_hex();
} }
/* test if the JS-interpreter is working properly */ /* test if the JS-interpreter is working properly */

View File

@ -17,14 +17,6 @@
along with gPass. If not, see <http://www.gnu.org/licenses/>. along with gPass. If not, see <http://www.gnu.org/licenses/>.
*/ */
// 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) { function pkdbf2 (password, salt, iterations, outlen) {
var result = ""; var result = "";
var temp = ""; var temp = "";
@ -34,17 +26,17 @@ function pkdbf2 (password, salt, iterations, outlen) {
for (i=1; result.length < outlen; i++) for (i=1; result.length < outlen; i++)
{ {
temp = hex2a(hmac256(salt + temp = hmac256(password, salt +
String.fromCharCode((i & 0xff000000) >> 24) + String.fromCharCode((i & 0xff000000) >> 24) +
String.fromCharCode((i & 0x00ff0000) >> 16) + String.fromCharCode((i & 0x00ff0000) >> 16) +
String.fromCharCode((i & 0x0000ff00) >> 8) + String.fromCharCode((i & 0x0000ff00) >> 8) +
String.fromCharCode((i & 0x000000ff) >> 0), String.fromCharCode((i & 0x000000ff) >> 0)
password)); );
temp_res = temp; temp_res = temp;
for(a=1; a<iterations; a++) for(a=1; a<iterations; a++)
{ {
temp2 = hex2a(hmac256(temp, password)); temp2 = hmac256(password, temp);
temp_res2 = ""; temp_res2 = "";
for(b = 0; b<temp_res.length; b++) for(b = 0; b<temp_res.length; b++)
temp_res2 += String.fromCharCode(temp_res.charCodeAt(b) ^ temp2.charCodeAt(b)); temp_res2 += String.fromCharCode(temp_res.charCodeAt(b) ^ temp2.charCodeAt(b));