Login   Register  
PHP Classes
elePHPant
Icontem

File: SHAREADME

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Chris Monson  >  SHA  >  SHAREADME  >  Download  
File: SHAREADME
Role: ???
Content type: text/plain
Description: A readme for the SHA classes here. Contains examples and explanations of how to use this stuff.
Class: SHA
Author: By
Last change:
Date: 14 years ago
Size: 6,827 bytes
 

Contents

Class file image Download
Chris Monson
June 30, 2000

The SHA classes contained here are useful for doing secure authentication over 
an insecure link.  The combination of SHA in Javascript and in PHP (or Perl) 
allows a server to do a secure challenge-response without ever sending the 
password over the internet in cleartext.  This is very important for those who 
would like to do authentication but do not have SSL capabilities on their 
hosting service.

Why use a pure PHP implementation of SHA instead of using the built-in 
authentication libraries?  Because those libraries use mcrypt, which must be 
compiled into the PHP interpreter.  If you are hosting your domain on a server 
that offers you little control over what is installed (a very common problem) 
then you don't have the option of installing mcrypt and compiling support for 
it into PHP.  You also don't have the option of restarting the web server, 
which would then be required.

Because of this, I implemented SHA in both Javascript and PHP, and I have used 
it in more than one project to allow for secure authentication over an insecure 
link (I don't have SSL access, either).

Here's how it works in basic terms:

1) The server generates a random number and a session ID, which it stores in a 
session table somewhere.  (If you don't know what a session is, go ahead and 
email me at ckmonson@burgoyne.com and I'll explain it to you).

2) It spits out a login page, which has the random number in a hidden form 
field.  This page also has some javascript code in it that can perform SHA.

3) The user enters his/her username and password, then clicks "login".

4) The login button is NOT a submit button, but a Javascript button that calls 
some code before submitting the form.  The code runs SHA on the password field 
and replaces the value with this new hashed value (secure).  It then takes this 
new value, combines it with the random number, and hashes it again.  It then 
overwrites the random number with an empty string so that it is not passed back 
to the server.  Finally, it submits the form.

5) The server receives this hashed value and the username.  It also knows what 
session it is dealing with, either because it stored it in a cookie or it used 
URL rewriting.  In either case, it looks up the user and gets the password from 
a database.  It hashes the password, then combines that with the random number 
stored in the session, and hashes it again.  If the two values match, then the 
user is authenticated, and the password was never sent over the wire.

In more mathematical terms, here is how things work:

S = Session ID
R = Random Number
U = Username
P = Password
[P] = Hashed Password
[anything] = Hashed anything

Server generates and sends the following:
S, R

Client gets U and P from the user.
It then sends to the server S, U, [R[P]]

Server looks up P' from U's record, and it gets R' from S's record.
Computes [R'[P']] and compares it with [R[P]].
If they are the same, that means that R=R' and P=P', so the user is
authenticated.  If not, the user is not authenticated.

I can't really give a good code example since this is very much based on 
session management, and everyone does that differently.  Still, to compute
the hash values as described above, here are the basics:

In Javascript (client-side.  Assume that the form is named 'f'):

<script language="javascript" src="shaobj.js"></script>
<script language="javascript">
function login() {
    sha = new SHA;
    var hash;
    // Create the password hash [P]
    hash = sha.block_to_string( sha.hash_text( f.password.value ))
    // Create R[P]
    hash = f.random.value + hash;
    // Create [R[P]]
    hash = sha.block_to_string( sha.hash_text( hash ));
    // Store it in the password field so that the password doesn't go over 
    // the wire:
    // Also obliterate the random number
    f.password.value = hash;
    f.random.value = '';
    // Finally, submit the form:
    f.submit();
}
</script>

In PHP (server side.  Assume that there is a way to get the current session
information and a way to look up the password (or passhash) for a particular
user).

-------------------------------
This is the part that generates the login screen.  This is necessary because
a session and a random number have to be generated.  This is the "challenge"
of "challenge/response":
-------------------------------

# Create a session record and set the session cookie
create_new_session();
# Generate a random number and set it in the session record (not the cookie)
set_session_random_number( get_new_random_number() );
# Serve up the login page with the random number in a hidden form field.
serve_login_page();

-------------------------------
This is the authentication part:
-------------------------------

include( 'sha.php' ); # some versions are called shaobj.php
$sha = new SHA();
# Remember that the global $password variable is really the hash value
# global $username has the username (form submission does all this)

# Get the session's random number somehow (up to you!)
$internalrandom = get_session_random_number();
$internalpassword = get_password_from_user( $username );
# Create [P'], then R'[P'], then [R'[P']]
$internalhash = $sha->hash_to_string( $sha->hash_string( $internalpassword ));
$internalhash = $internalrandom . $internalhash;
$internalhash = $sha->hash_to_string( $sha->hash_string( $internalhash ));

if ($internalhash = $password) {
    # Do authentication stuff to the session
    mark_session_authenticated();
    serve_home_page_or_something();
}
else {
    show_authentication_error();
}

-------------------------------

Hopefully that should get you enough information to actually use these classes.
Please let me know if you have any trouble at all getting stuff to work, or
understanding the examples here.  I am very glad to help where I can.

Also, I am interested to know who is using these and for what projects, mostly
because I like to think that something I have done is useful for someone else.
So, drop me a line if you find these useful.

Finally, you can get the latest version of these components on my website at
http://bouncingchairs.net/monson/oss

If that doesn't work, just go to bouncingchairs.net and see if you can find
the code.  It's all Open Source and Free Software, so it should be fairly easy
to spot.  As a final note on my website, I am going to be moving all of my code
over to highentropy.com when I have some free time.  Right now that site isn't 
up at all, and when it is I'll put a link to it from bouncingchairs.net, which 
I also own.  One way or another, you should be able to find what you are looking
for.

Chris: ckmonson@burgoyne.com