how to properly secure non-ssl logins (php + ajax)

Jeffrey I. Schiller jis at mit.edu
Mon Feb 16 22:50:30 EST 2009


I think you are close, but are probably doing way too much work.

First let's define a function HMAC_MD. HMAC is defined in RFC2104
and represents the current best current practice for using a hash to
"sign" a data value. It takes:

  result = hmac_md(key, value)

You can use hmac with MD5, SHA1, SHA256... whatever. You will likely
find libraries that already implement this in various languages.

Below "SHA" means SHA1, SHA256, your choice.

We'll assume each user has a password which is stored on the
server. For a bit of extra security I would have the server store it
as a SHA hash of the actual password.)


For authentication you do a challenge response.

   Server                         Client
    nonce           ====>
                    <===        username, hmac_md(sha(password), nonce)

The trick is to ensure that the nonce is not re-used. There are
several ways to do this. One way is to store it in a table:

  crate table nonces (
       nonce varchar(128),   # Probably enough
       ts  timestamp,
       used Boolean )

When the server gets the reply it looks up the user's "sha(password)"
which is stored in the user account table. It then verifies that the
nonce value is in the nonces table and that used is False. It then
verifies that the timestamp is "fresh" (you can decide this). Upon
use, the nonces table is updated to set used to True. A second login
attempt would require a separate nonce. Once a nonce is no longer
"fresh" it can be purged from the nonces table (so you don't have to
store these forever). Obviously the server computes
hmac_md(sha(password), nonce) and verifies it is the value received
from the client.

There are a copy of gotchas here. The biggest is how you initially
setup the shared secret (aka the password). Without public key
operations there is no good way to create accounts (unless this is
done administratively, effectively "off line"). SSL of course can
solve this (but you don't want to use SSL). You can also attempt to
implement RSA in javascript and PHP (well, I'm sure routines exist for
PHP). You can then download a public key in your javascript code for
account registration. The user's browser can then compute
sha(password) and send it encrypted in the public key (or encrypted in
a data encrypting key which is encrypted in a public key).

I don't know how amenable javascript is to doing RSA. Years ago (when
computers were much slower) I wrote a Java Applet that did RSA in the
applet for account registration at MIT. It wasn't very fast, but it
was good enough for a one-time registration applet. Heh heh, we still
use it today!

Now of course I really cannot end this message without throwing in the
obvious caution that without SSL your authentication is pretty
weak. Even though you have not exposed the user's password, once
logged in PHP uses a session cookie. This cookie, although of limited
lifetime, is now available to the eavesdropper to steak and abuse. I'm
not even sure that PHP ensures that a cookie is coming from the same
IP address it was issued to (and in fact you cannot usually implement
such a restriction because some environments [aka large NATs and other
crud] can result in a legitimate user's traffic coming from different
IP addresses even within the same web session!).

And of course all of your data is also exposed, both for viewing and
for modification in flight.

Last I checked, SSL certificates could be had for the $20/year range,
so I don't see how that is cost prohibitive!

Modern hardware also does SSL pretty darn fast. You really have to
have a very high traffic site before it becomes a problem. There
actually aren't that many high traffic sites out there. Most
organizations may think their sites are high traffic, but they rarely
are.

                        -Jeff

----- "Rene Veerman" <rene7705 at gmail.com> wrote:

> 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.

--
========================================================================
Jeffrey I. Schiller
MIT Network Manager
Information Services and Technology
Massachusetts Institute of Technology
77 Massachusetts Avenue  Room W92-190
Cambridge, MA 02139-4307
617.253.0161 - Voice
jis at mit.edu
========================================================================

---------------------------------------------------------------------
The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majordomo at metzdowd.com



More information about the cryptography mailing list