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"/>
   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

Reply via email to