[JDEV] Expl.: Why digest auth does not work with hashes passwords
m at tthias.net
Tue Sep 16 03:38:26 CDT 2003
Very often on this list and JADMIN I replied to mails asking why the
server stores passwords in plain text. Maybe its time to write an
additional mail and explain why storing hashes of passwords can not be
used together with a typical authentication scheme that uses hashes on
(This mail addresses only storing hashes in the userbase - using
(twoway) encryption for the passwords is another thing)
How hashes work
A typical hash function like MD5 or SHA1 is a function with two
parameters, that is applied byte by byte to the string you want to get a
hash of. The function returns an updated hash for each call, the
parameters are the former hash and the byte you want to add. The initial
hash value used for the first call of the one-way function is fixed,
e.g. just zero. If I want to calculate the hash for the string
"Jabber" I just calculate:
hash = f(f(f(f(f(f(0,'J'),'a'),'b'),'b'),'e'),'r')
How digest based authentication works
To check a password without transmitting it in clean over the network,
often the following scheme is used:
- The server sends a random value to the client
- Both server and client append the password to this value.
- Client transmits the result to the server
- Server compares both, if they match the client has used the same
password for calculation the hash value.
With this scheme the server has to know the plain password as it could
not calculate the same hash as the client and it could not verify it
One thing that is probled sometimes: Instead of prepending the random
value to the password, one could prepend the password to the random
value. In this case the hash function is first applied to the password
and then the random value can be applied afterwards. In this case the
intermediate hash value after the password could be stored in the user
base and the final hash value could be calculated starting with this
intermediate hash value and only calculating the additional function
calls to add the random value.
This is a BAD idea that offers security! If the random value
is the last thing you apply the hash is not a real one-way function
anymore. Because the string you are hashing is only used byte by byte
one could sniff both the random value and the final hash value. Having
both in this scheme makes a brute force attach easier: You only have to
to find a value v1 that results in the final hash if you apply the last
byte. Then you search for a value v2 that results in the value v1 if
you hash it together with the second last byte and so on.
(With the original digest authentication this is not possible as an
attacker don't know the last bytes that have been hashed.
An other attempt to store hashed passwords:
- Keep the digest authentication protocol as it is but let the server
not only send a random value but also a fixed value to the client.
- This fixed value was used by the server to hash the password.
- The client hashes the password with the fixed value and uses the
result instead of the password to do the same calculations as in the
original digest authentication scheme.
- The server can calculate the same by using the stored hashed password
and the random value.
- The client transmits this to the server which can compare it.
Basically this results in the same security as the original protocol.
You don't get additional security as it is enough to know the hash that
is stored on the server to sucessfully authenticate against the server.
The real password is not needed anymore to authenticate. Therefore you
can view the stored hash as the password. Again it is enough to have
access to the userbase to compromise their accounts.
You only get additional security for users using the same passwort for
many systems as you don't use their password on the Jabber network but a
password that is derived from their password.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Size: 189 bytes
Desc: not available
More information about the JDev