>>> [W]ould anyone be interested in a one-way function for passwords
>>> that I built on top of md5?
>> Do it. Exportability would not be the only plus with using md5.
> Replacing crypt(3) with MD5, if done properly (i.e., a salt was still
> there, arbitrary length passwords were now permitted) would be a
> great boon for everyone, not just those overseas.
I have seen some three or four positive comments and no negative ones
at all. Here's the algorithm I was using in the other setup where I
have been using md5 to hash passwords. The reason I'm quoting it here
is that it is likely that crypt(3) is being used in ways I'm not aware
of, and I don't know whether the change in paradigm this would involve
will break anything. In particular, what I describe below does not
permit the caller to select a salt; does this matter? hash_password
could, obviously, take an arbitrary-length salt buffer as an argument,
leaving it up to the caller to supply one.
The conversion from binary to base 94 would probably have to be changed
for this to be a drop-in crypt(3) replacement, probably to use a
base-64 conversion similar to that used now; the salt buffer should
probably use getpid() and getppid() instead of random().
hash_password (input: cleartext password, output: hashed password)
fill a buffer with salt-type data. I currently use the time of
day (the whole struct timeval, including usec) and a call to
random(), which makes sense in the context this is being used.
initialize md5
feed the salt buffer to md5
express the 16-byte md5 output as 20 bytes in base 94;
call the resulting string the salt string
initialize DATA to the cleartext password
repeat ROUNDS times (ROUNDS is a compile-time value, currently 64)
initialize md5
feed DATA to md5
feed the salt string to md5
feed DATA to md5
feed the cleartext password to md5
feed DATA to md5
take the md5 result and express it in base 94; set DATA
to the resulting string
hashed password is ROUNDS (in cleartext decimal, followed by a
terminating dot) concatenated with the 20-byte salt string
and the 20-byte final value of DATA (a little over 40 bytes).
check_password (input: cleartext password and stored hashed password,
output: boolean indicating password correctness)
initialize DATA to the cleartext password
extract ROUNDS value from the hashed password; if it is out of
range (currently, 1..10240), or the string is otherwise
invalid (eg, wrong length), return "password incorrect".
extract salt string from the hashed password
initialize DATA to the cleartext password
repeat ROUNDS times
initialize md5
feed DATA to md5
feed the salt string to md5
feed DATA to md5
feed the cleartext password to md5
feed DATA to md5
take the md5 result and express it in base 94; set DATA
to the resulting string
if the final value of DATA matches the rest of the hashed
password, return "password correct"; otherwise, "password
incorrect".
der Mouse
mouse@collatz.mcrcim.mcgill.edu