Hi.
Recently, on both the jQuery(.com) and PHP mailinglists, a question has
arisen on how to properly secure a login form for a non-ssl web-application.
But the replies have been "get ssl".. :(
I disagree, and think that with a proper layout of authentication
architecture, one can really secure a login system without having the
administrative overhead of installing SSL everywhere, and the monetary
cost for a SSL certificate for each domain.
I wish to code such a solution into a really-free library (so probably
LGPL or GPL + MIT) over the next 2 to 5 months.
This library would be a complete SQL, PHP & javascript package (jQuery
"plugged in"), targetted for the novice programmer.
I'm halfway (or more?) there, i think.
For my own CMS, i have taken the following approach, which i'd like to
hear your improvements on:
(For onewayHash() i have MD5 and SHA256 implementations in both JS and
PHP..)
//// SQL:
create table users (
user_id integer,
user_login_name varchar(250),
user_login_hash varchar(250),
user_password_hash varchar(250),
....other fields....
primary key (user_id)
);
create table preferences (
pref_system_hash varchar(250)
....
);
//// PHP (pseudo-code) , on system installation:
preferences.pref_system_hash = onewayHash ( randomStringLength(100) );
//// PHP , on user-create:
users[user_id].user_login_hash = onewayHash(user_login_name +
preferences.pref_system_hash);
users[user_id].user_password_hash = onewayHash
("someGooodPasswordNot" + preferences.pref_system_hash);
//// PHP, on request of a login form:
challenge = makeNewChallenge ();
//checks since when [browser IP] has last received a new
challenge, if < threshold : make a new challenge. else return old challenge.
//a challenge is a random string (+ special chars) pushed through
the onewayHash function.
html = '
<form id="loginForm">
<input type="hidden" id="sh" name="sh"
value="preferences.pref_system_hash">
<input type="hidden" id="ch" name="ch" value="challenge">
<input id="plain_user" name="plain_user"/>
<input id="plain_pass" name="plain_pass"/>
<input type="hidden" id="user_hash" name="user_hash"/>
<input type="hidden" id="pass_hash" name="pass_hash"/>
</form>
';
sendHTMLtoBrowser (html);
//// Javascript: on page with login form:
jQuery('#loginForm').submit (function () {
var sh = jQuery('#sh')[0]; //same for ch, plain_user,
plain_pass, all the inputs in the html form.
....
user_hash = onewayHash ( onewayHash ( plain_user.value +
sh.value ) + challenge );
//same for pass_hash basically
plain_user.value = ''; //clear out the plain text fields so
they dont get transmitted (same for plain_pass ofcourse)
jQuery.ajax ( /* submit login form through POST, handle
results */ )
}
//// PHP, on receiving the login form data:
// walk through all the records in users table, for each, calculate:
user_hash = onewayHash ( users[user_id].user_login_hash +
challenge );
pass_hash = onewayHash ( users[user_id].user_password_hash +
challenge );
// if they match what was sent, then it's the user we're looking
for with the right password, so their $_SESSION['authenticated_user'] =
updated.
////
If you have a completely alternative way of securing a non-ssl login
form, i'd like to hear about it too.
---------------------------------------------------------------------
The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majord...@metzdowd.com