Friday, May 25, 2012

Password Storage with Salted Hashes


Password storage is a hugely important issue for any application that makes use of passwords as an authentication mechanism.  One of the primary rules of password storage is that passwords should never be stored in plain text, but should instead be stored in a hashed form.  Hashes are one way cryptographic functions that provide a unique output for every input, and, as such, as long as the user always types in the correct password, the hash of the password should always result in the same value.  Any difference in the supplied password will result in a different hash value.  Thus as long as the hash of the typed in password matches the stored hash value, it can be concluded that the proper password was entered and the user can be given the appropriate access to the system.  The one way nature of hash functions works to improve security, because theoretically it should not be possible to determine the password value used to create the hash (e.g. without resorting to techniques like brute forcing, rainbow tables, etc). 

The security of stored passwords can be even further improved by using a strong hash function such as SHA-512 over older hash functions like MD-5 or SHA-1.  Moreover, salting hashes can provide a further means improving the security of stored passwords, as salts can work to nullify the usefulness of rainbow table based attacks.  A salt is a set of random bits that is also provided as input to the hash function.  Ideally each user of your application should have a unique salt applied to his password hash function.  In Perl, this is actually quite easy to achieve with the Crypt::Salted Hash module (http://search.cpan.org/~esskar/Crypt-SaltedHash-0.06/lib/Crypt/SaltedHash.pm).  Let’s consider the following snippet of Perl code which uses the module to create the salted SHA-512 hash of the supplied password.  

#!usr/bin/perl

use Crypt::SaltedHash;
use strict;
use warnings;

my $password='password';

#creating the salted hash
my $crypt=Crypt::SaltedHash->new(algorithm=>'SHA-512');
$crypt->add($password);
my $shash=$crypt->generate();
my $salt=$crypt->salt_hex();

print "Salted Hash= $shash\n";
print "Salt= $salt\n";

 
The module automatically generates a random salt value when it generates the hash, and this can be verified by running the same code multiple times and seeing the different salts and salted hash values generated. 

The same module can also be used to verify that the proper password was entered, by comparing the supplied password with the stored salted hash as seen below.  If the password is found to be the same as the one used to create the salted hash, the validate method will return a value of “1”.

#verifying the salted hash
my $crypt2=Crypt::SaltedHash->new(algorithm=>'SHA-512');
my $verified=$crypt2->validate($shash, $password);
if($verified==1){
    print "This is the correct password\n\n";
}
else{print "This is the wrong password\n\n";}
 
To show what would happen if an incorrect password was supplied, consider the following code snippet.  Note how the “This is the wrong password” message is printed.  

#showing what would happen if the password was wrong
$password='passw0rd';
my $verified=$crypt2->validate($shash, $password);
print "$verified\n";
if($verified==1){
    print "This is the correct password\n\n";
}
else{print "This is the wrong password\n\n";}

Kobo has over 2 million ebooks to choose from!

2 comments:

szabgab said...

Where do you get the $shash from for the ->verify call?

cfrenz said...

If you are looking to just test the sample code, it will run if you paste all 3 snippets into one script. In that case $shash will come from the first code snippet. In a more real life scenario, $shash would likely be retrieved from the DB you use to maintain credentials.