How to make your login page more secure without SSL : Part 2
Thursday, May 15, 2008, 05:49 PM -
Design concepts
Powered By ReadTheWords.com
In
yesterday's post, we discussed about the pitfalls of sending plain text password during a user's login process into a website. We concluded that to prevent Bob from doing a
man-in-the-middle attack, we need to achieve the following while posting the login form:
-- We should not send the password or any reversible derivation of Alice's password.
-- Whatever we send as replacement of the password should be different every time.
-- And yet the server should be able to authenticate Alice.
Consider the following steps:
a. The server gave the browser a number, k, via a java script variable. This random number is stored in the server.
b. User types in his password in the form along with his username.
c. The MD5 sum of the password, p is calculated as H(p). It is then appended to the key, k. Lets call it H(p)+k.
d. The MD5 sum of (H(p)+k) is calculated. as H(H(p)+k). This is what is then sent to the server.
e. The server has the MD5 sum of the password, H(p) and the key, k. It can derive its own version of H(H(p)+k). If the two matches then the user is authenticated.
Lets analyze the above steps now. In step (c) we had H(p)+k. Why could this be not sent instead of doing another md5 sum. As data is transferred in plain text, Bob who is sitting in the n/w saw that the server gave the key, k. He also saw that H(p)+k was transmitted to the server. He could now get H(p). Later he makes a request to server for a new key, k~ and sends back H(p)+k~ to authenticate himself and he suceeds.
Lets try to now see if Bob can make use of what we finally transmitted in step (d). We transmitted H(H(p)+k). Bob has this and k. Bob cannot practically get H(p) from what we transmitted -- because an MD5 sum is a one way transformation. Moreover we transmitted is only of one time use because of k. Bob just cant make use of all the data he has to authenticate himself successfully unless he knows the user's password p.
There is a flaw however in this approach, and it in in the key, k itself. The server has no way of knowing to whom(for which user's login) the key, k was sent to. So it needs to keep k constant and not random. If k is constant then H(H(p)+k) which is actually sent over the n/w is constant for a given user. And Bob can use it. The server at best can keep k constant for a short period of time and there after start using a new key, k~. This gives a small window for Bob to authenticate himself. So Bob needs to be on his toes to break in. But the sad part is that Bob will be on his toes, because he is Bob.
If however the server knew that Alice is going o login, then it can create a new random key every time and keep it beside the Alice's credential in the DB. The server will only know that Alice is trying to login if the browser sent a request with only the username first. This means a two stage authentication. Here are the steps again.
1. Alice opens
www.example.com/login.php in his browser. She gets a form asking just the username. Alice submits form. (Bob sees that Alice is trying to log in).
2. Server generates a random key,k, stores in in DB against Alice's row in the DD, and sends back a page with key, k as a javascript variable. (Bob also see the key k). This page asks Alice to enter her password.
3. Alice types in the password in the form. Browser calculates hash of p, H(p). It then adds k to it, i.e., H(p)+k. Then it rehashes it as H(H(p)+k). When Alice submits the form, H(H(p)+k) along with username "Alice" is sent to server. (Bob sees that H(H(p)+k) as a stream of data).
4. Server calculates it own version of H(H(p)+k) and verifies it with the incoming data. Alice is authenticated if they match.
This time however Bob cant make use of anything to authenticate himself as Alice to the server.
The pain here is that the login is a two stage formality. Alice first enters just her username and fills her password in the second form. Is this acceptable?
There is one remote scenario where it would fail. Alice should not just enter her username and then go to another computer and restart the session again, enter her username and come back to her first computer and enter her password. Authentication would fail. This is definitely acceptable.
All these just because you could not make your server run a SSL version of the web server.
In all the discussion above I have used the term md5 sum instead of using the term "hash" which is more commonly used to describe such an issue. A more advanced version of such a hash is SHA1 sum which is gaining popularity.
Resources:
Javascript implementation of MD5 checksum.Digest::MD5 - Perl interface to the MD5 Algorithm.
MD5sum in PHP.
Happy login.//