Passwords must not be generated with hash algorithms such as Digest::MD5 or Digest::SHA1, as these do not implement salting and other security measures required by passwords. Instead, use the built-in Perl crypt function or Crypt::PasswdMD5 module to produce passwords. Examples of the legacy Unix Data Encryption Standard (DES) and newer Message Digest Algorithm #5 (MD5) encrypted passwords are shown below.
des lRk62l2WdzX1k
md5 $1$43SgvNjO$5a68aNBxASAChyjBZ3hj2/
Most modern Unix systems have updated the traditional crypt function to also generate MD5 or Blowfish encrypted passwords. For portable code, use the module Crypt::PasswdMD5 over an operating system specific crypt call.
Alternatives to or improvements over passwords include Kerberos, OpenSSH public key authentication, and cookie-based web authentication.
The crypt-example script demonstrates how to generate traditional DES passwords and new MD5 based ones. The code is duplicated below. Avoid using crypt, as modern systems can break traditional DES passwords very quickly. MD5 will suffer a similar fate in a number of years, due to increasing processor power and storage space yielding allowing faster brute force and storage of pre-computed hash to password lookup tables.
#!/usr/bin/perl -wl
use strict;
use Crypt::PasswdMD5 qw(unix_md5_crypt);
my @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' );
# this takes password as argument: good for simple example, bad for
# security (perldoc -q password)
my $password = shift || die "usage: $0 password";
my %encrypted;
# generate traditional (weak!) DES password, and more modern md5
$encrypted{des} = crypt( $password, gensalt(2) );
$encrypted{md5} = unix_md5_crypt( $password, gensalt(8) );
print "$_ $encrypted{$_}" for sort keys %encrypted;
# uses global @salt to construct salt string of requested length
sub gensalt {
my $count = shift;
my $salt;
for (1..$count) {
$salt .= (@salt)[rand @salt];
}
return $salt;
}
The crypt function documentation covers how to verify a password against an encrypted password. Briefly:
#!/usr/bin/perl -l
print "match" if crypt('password', 'QQjYbirnCGD7A') eq 'QQjYbirnCGD7A';