I was trying to design an authentication system that would make it much harder to guess a password via brute force, and reduce the risk to a user if the hashed password was stolen through a snooping based attack. Also, since my client side code will be easily view-able by those wishing to see it (it is in an interpreted language, however, I do encrypt and obfuscate the distributed client), I wanted to be able to prevent an attacker looking at the source to impersonate a user easily. Security through obscurity is NOT security.
Here is the algorithm I thought up. I wanted to submit it to public examination because cryptography algorithms always work better when subjected to as many opinions as possible, IMHO.
(All hashes are computed with the SHA-2 and a 512 bit block size. This algorithm is not known to be vulnerable to any collision or pre-image attacks, and is a secure cryptographic hash function.)
The user provides an any-character/symbol/number username less than 30 characters and an any-character/symbol/number password that is between 8 and 200 characters long.
The username is hashed.
The hash of the username is added onto the end of the users password as a salt.
The salted password is hashed, and then that hash is hashed.
The current date and time are requested from the authentication server, and are then hashed.
The hash of the timestamp is added to the username/password hash as what I'll call a 'time dependent salt'. This last combination is then hashed to produce the final authentication hash.
The username, the timestamped hash, the salted password, and the time used to generate the time dependent salt are sent to the server via a TLS/SSL connection.
The server verifies that the recieved timestamp is in the last minute. If it is not the server will indicate that the authentication failed.
The server hashes the username/salted password and compares that against the stored database salted/password hash. If they do not match the authentication fails. (To clarify, the server has a hash of salted password hash. It verifies that against a hash of the salted password hash given by the client.)
The server calculates a hash of the timestamp sent by the client.
The server hashes together the generated timestamp hash and the salted password hash to form the authentication hash.
It compares the authentication hash it produced with the authentication hash sent by the client. If they are the same, it reports authentication. Otherwise it reports a failure to authenticate.
If I am correct, I believe this authentication scheme does indeed make brute forcing a password nearly impossible, and makes a password stolen through snooping only useful for a full minute.
However, what it does not protect against, as I think it is impossible, is passwords stolen from the user as they are input into the client. Spyware would be able to steal the actual username and password.
EDIT 1 :: Fixed the authentication process so that the server does not store the salted password hash, only a hash of that value. This prevents an attacker with access to the database from knowing the original password. The reason this has to be done is the hashed value of the salted password hash is the password from the server's point of view. Storing the salted password hash in the database would be the same as storing all user's passwords in plaintext.
EDIT 2 :: Fixed the scheme so that the authentication relies on the server's time, not the client's.
EDIT 3 :: Made the password length less restrictive, but kept it reasonable.