http://qs321.pair.com?node_id=62392


in reply to Best way to hide passwords.

If you're using a '.htpasswd' style system, use MD5 crypt instead of DES. MD5 is much harder to crack than the simple DES encryption used by default, and it's perfectly compatible, at least when it comes to using Perl and crypt(). More on that in a second.

If you are storing passwords on your system, you want to ensure that even if the file should fall into the wrong hands, there is no easy way into your system. This is effected by having the passwords stored encrypted, just like they are in the UNIX '/etc/passwd' file (or, '/etc/shadow' which is more common these days). Since the passwords are sent via HTTP or a cookie, or some other mechanism in a non-encrypted way (even over "encrypted" SSL, they are decrypted into plain-text by the server for authentication), the encrypted passwords are no use since you still don't know the password to gain access.

As distributed.net proved, DES encryption is quite flimsy and hardly provides any security at all. You should use MD5 instead, which is a much more robust algorithm.

The trick to using MD5 instead of DES is in how you supply the "salt" to the crypt() function. If you follow the docs, you would supply two random letters. For MD5, you use eight, which allows for more variations when it is stored encrypted, which translates into better security.

Here's a standard-issue MD5 salt generator:
my (@chars) = ('a'..'z','A'..'Z','0'..'9','.','/'); sub md5_salt { my ($return) = '$1$'; $return .= $chars[rand($#chars+1)] foreach (0..7); return $return; }
It is used just like always:
$encrypted_passwd = crypt($passwd, md5_salt()); # For testing... if (crypt($passwd_guess,$passwd_encrypted) eq $passwd_encrypted) { # Got it. }
So you get passwords that are encrypted like:
$1$1PUXLuZE$P.LfclRO9SKqTf2BQK.yD1 $1$t7AJPueY$1ivH/pIhxnjEIx10QzaIi. $1$lvWzTNnn$JFsfy9ALLJS3Dpi4OHMVo1
Which are, incidentally, all the same password ('shjdajksds') with different "salt".

If you are using a database, such as MySQL, you could use the built-in PASSWORD() function which does the encryption for you. Or, you could use your own. It depends on the security of your application.

What you should not ever do is store passwords as plain-text. So, yes, encrypt the passwords in the file, but don't bother encrypting the whole file.

Replies are listed 'Best First'.
Re: Re: Best way to hide passwords.
by dvergin (Monsignor) on Mar 06, 2001 at 05:12 UTC
    Note for Windows folks: getting crypt to supply MD5 encryption as described by tadman is not supported in ActiveState Perl.
    print "Long: ", crypt('shjdajksds', '$1$abcdefgh'), "\n"; print "Short: ", crypt('shjdajksds', '$1' ), "\n";
    Using ActiveState build 623 this produces:
    Long: $1G0qFXI2hLqU Short: $1G0qFXI2hLqU
    But on Linux we get:
    Long: $1$abcdefgh$LBpJSL4DEIVrkp1RZO36I0 Short: $1KHjUeDByb1c
    As is often the case YMMV. (Can we assume that Linux Perl is calling a system function which supports the MD5 option?) The standard Perl doc page for crypt doesn't mention this behavior. Nor does   'man crypt'   on my Linux system.

    Where is it documented?

    And I don't even want to talk about why the short versions are different on the two systems. Yuck! (I ran this several times to be sure.) Are 'standard' passwords not sharable across platforms?