[Memphis.pm] using md5 hashes for passwords

Brock Sides bsides at towery.com
Mon Mar 13 12:47:17 CST 2000


First, I'd like to welcome to everyone subscribed to the Memphis Perl
Mongers mailing list. There are eight people subscribed so far. I hope
that this group will become an active one, holding meetings, doing
presentations, having guest speakers, etc. 

At the very least, I hope the mailing list will become a useful resource
for the Perl programmers in Memphis. Local lists, having lower volume, 
are a much safer place for new users (and experienced users) to ask
questions without fear of the wrath of Tom Christiansen. :)

I guess all of you heard about this through the GOLUM list. I'm sure there
are a lot of Perl users out there who aren't into Linux as well, but I'm
not sure how to reach them. Any suggestions?

Anyway, here's a question to get us started. More an algorithms question
than a Perl question, but the implementation lends itself to being done in
Perl, as so many problems do.

I'm sure we all know how to create and verify hashed passwords using
Perl's built-in crypt function:

# create hashed password
my $plaintext = "password";
my $salt = &salt; # returns random two bytes of salt
my $crypthash = crypt($plaintext, $salt);

# verify password
my $crypthash = "SA01VjfokepR.";
my $plaintext = "password";
if ($crypthash eq crypt($plaintext, $crypthash)) {
	# it's the right password
}

However, this of course suffers from all the problems associated with Unix
crypt(), such as an eight-byte limit on password length.

If one wanted to go about using MD5 hashes instead, what would be the
proper way to to that? You could just hash the password, like this:

use Digest::MD5 qw(md5_base64);
my $plaintext = "password";
my $crypthash = md5_base64($plaintext);

But I have a feeling that you ought to be salting the hash somehow, to
make it harder to build a dictionary, and make it more time-consuming to
crack multiple passwords. (However, I note that the SHA hashes that
Netscape Messaging Server uses to store passwords are not salted in any
way.)

Am I right? How is it done by Linux, if you're using MD5 passwords?

Maybe something like this:

# create hash
use Digest::MD5 qw(md5_base64);
my $plaintext = "password";
my $salt = &salt; # generate random N bytes of salt
my $crypthash = $salt . ":" . md5_base64($salt . $plaintext);

# verify password
my $crypthash = "SALT:fXt+cRfLdw5YFJsibzeKFQ";
my $plaintext = "password";
my ($salt, $md5) = split ":", $crypthash;
if ($md5 eq md5_base64($salt . $plaintext)) {
	# password is correct
}

Obviously I shouldn't be using : as a salt/hash delimiter, since it tends
to be used as a username/password delimiter. But other than details like
that, is this the proper algorithm? (I.e. How does Linux do it?)

And are other sorts of hashes I could be using? SHA or MD2, I guess,
since they're part of the Digest::MD5 package. What about Blowfish hashes?
Anybody knowledgeable on the merits of various hashing algorithms?

--
Brock Sides
Unix Systems Administration
Towery Publishing
bsides at towery.com


----------------------------------------------------------------------------
To Unsubscribe, please send email to majordomo at pm.org
with 'unsubscribe memphis-pm-list' in the body of the message.
----------------------------------------------------------------------------




More information about the Memphis-pm mailing list