views:

1066

answers:

5

I'm working with Subversion based on Windows and would like to write an easy utility in .NET for working with the Apache password file. I understand that it uses a function referred to as MD5Crypt, but I can't seem to find a description of the algorithm beyond that at some point it uses MD5 to create a hash.

Can someone describe the MD5Crypt algorithm and password line format?

+2  A: 

You can find an implementation of md5crypt in the tcllib package. Download is available from sourceforge.

You can also find an example of an apache-compatible md5crypt in the source code for the CAS Generic Handler

Espo
+1  A: 

MD5Crypt is basically a replacement for the old-fashioned unix crypt function. It was introduced in freebsd, and has been adopted by other groups as well.

The basic idea is this:

  • a hash is a good way to store a password
    • you take the user's entered password and hash it
    • compare it to the stored hash
    • if the hash is the same, the passwords match

But there's a problem:

  • Suppose you pick the password "jeff" and I also pick the password "jeff".
  • Now both of our password hashes are the same.
  • So if I see the stored hash codes, I will know your password is the same as mine, "jeff".

So, we can add a "salt" string to the password.

  • This can be any random thing.
  • Suppose for your account it is "zuzu" and for my account it is "rjrj".
  • Now we hash the string "jeffzuzu" for your password, and "jeffrjrj" for my password.
  • Now we have different hash values for our password.
  • We can safely store the salt value with the hashed password, since even knowing the salt value won't help to decode the hash.

You mention .net, there's a pointer over in another forum to this:

System.Security.Cryptography.MD5CryptoServiceProvider md5 = new
System.Security.Cryptography.MD5CryptoServiceProvider();

string hash =BitConverter.ToString((md5.ComputeHash(
System.Text.ASCIIEncoding.Default.GetBytes(stringtohash) ) ));

HTH!

Mark Harrison
A: 

Thanks for the feedback. What I am hoping for is a description of the process to generate the password line rather than some code (in an unfamiliar language) to try to parse. But, the tcllib page did give me a test sample:

% md5crypt::aprcrypt password 01234567
$apr1$01234567$IXBaQywhAhc0d75ZbaSDp/

Given the assumption that this is actual output of the tcllib function and my understanding that the password line is a dollar-sign delimited list of "magic" (the "apr1"), followed by the "salt" and finally the resulting hash ... neither of the supplied chunks of .NET code produce the needed output. I got "ZPscNmUeIPzAE3K8ir7sjA==" for the resulting hash.

My belief is that there are one or more other steps to the process and I would like to get them documented here in a reasonably language-agnostic way so anyone can take the description and implement it in their language du jour.

Lee
please update your original question.
hop
i don't think the code i posted a link to is too hard to follow. what's a "reasonably language-agnostic" anyway?
hop
A: 

You can find implementations in other languages on Google Code Search

Michał Piaskowski
+2  A: 

The process is rather involved... the salt and the password are hashed together not once, but 1000 times. Also, the base64 encoding uses a different alphabet, and the padding is removed from the end.

The best thing would probably be to find a library to use, like glibc under cygwin.

Since you code against Apache anyway, have a look at Apache's implementation of crypt-md5.

The original algorithm (I think) in C can be found here. It differs from the above implementation only by the different magic number.

hop