NAME
Password::SaltSha - The great new Password::SaltSha!
VERSION
Version 0.01
SYNOPSIS
Creates a 40 ASCII character salt, and salts it into a password, returning the SHA-256 (SHA2) salted password as a hex string.
use Password::SaltSha qw(
salt
salted_sha_pass
salt_n_salted_sha_pass
);
my $salt = salt();
my $salted_pass = salted_sha_pass( $password, $salt );
my $aref = salt_n_salted_sha_pass( $password );
$salt = $aref->[0];
$salted_pass = $aref->[1];
use salt
if all you want is a 40 ASCII character salt. Use salt_n_salted_sha_pass
if you want to generate a salt and salted SHA-256 password pair, perhaps for storage in a user database. Use salted_sha_pass
if you want to check whether a given clear text password and salt match the salted and SHA-256 encrypted one generated by salt_n_salted_sha_pass
.
EXPORT
Nothing exports by default. May export salt
, salted_sha_pass
, and salt_n_salted_sha_pass
.
SUBROUTINES/METHODS
salt
Accepts no parameters. Returns a string of 40 random ASCII characters that are appropriate as salt.
salted_sha_pass
Accepts a password, and a salt string. Returns a hex representation of a SHA-256 (SHA2) that results from concatenating the password with the salt. The result will be a 64 digit hex string.
This function is useful in checking to see whether a given salt and clear-text password can be hashed to match some previously stored SHA2 hash.
salt_n_salted_sha_pass
Accepts only a password as a paramater. Returns an array reference. The first field will be the random salt generated (40 ASCII characters). The second field will be the SHA-256 (SHA2) that resulted from concatenating the password provided with the random salt generated.
This function is useful in generating (possibly for storage in a database of users) a salt and a SHA-256 hash of the clear text password combined with the salt.
EXAMPLE
my $user = 'john doe';
my $pass = 'Super_Secret';
my $credentials = salt_n_salted_sha_pass( $pass );
my $salt = $credentials->[0];
my $pass_sha_as_hex = $credentials->[1];
# Assuming you've got some 'store' function...
store( $user, $salt, $pass_sha_as_hex );
# Later on...
my( $user_login_name, $user_clear_pass ) = get_login();
my( $stored_salt, $stored_pass_hash ) = fetch( $user_login_name );
if( salted_sha_pass( $user_clear_pass, $stored_salt ) eq
$stored_pass_hash
) {
print "$user_login_name: You are the winner!\n";
}
Assuming you've filled in the blanks (created your versions of store()
, get_login()
, and fetch()
, and assuming the user has given you a valid password for the given username, the output will be:
john doe: You are the winner!
The typical use case will be to generate a salt and a hashed password, store them in a database of users, and then later retrieve the salt and the hashed password to verify that the clear text password provided at some user login hashed together with the salt returns the same password hash that was previously stored in the database.
It is safe (and normal operating procedure) to store the salt within a database. The salt plus a password hash cannot be used to reverse-engineer original clear-text passwords. However, a unique salt per user that is hashed along with a clear text password does create a stronger password hash, and is more effective against rainbow attacks than simply storing a hash based entirely on just a password.
WHY?
Because I got tired of implementing something similar to this every time I build an application that uses logins.
If you find it useful, that's nice too. ;)
CAVEATS AND OPINION REGARDING EFFECTIVENESS
The salt generation routine is based on String::Random. It is designed with the philosophy that a pseudo-randomly generated salt of characters from the list of [A-Za-z0-9./]
, which provides 60 bit-pattern possibilities per character, in a length of 40 characters, will provide enough entropy to harden just about any user supplied password. The salt length of 40 was chosen because that gives sufficient bits of entropy to seed even short passwords, yielding near maximum entropy in the resulting SHA2-256 hash.
This module is effective in significantly increasing the difficulty of brute force or rainbow attacks against the SHA2-256 hashed representation of a password. But there are no guarantees as to how effective it is.
That said, it is quite strong despite the fact that its strings are generated using Perl's basic random number generator. Why? Because SHA2-256 is already strong, and any difficult to predict salt will provide even better strength. Despite these salts being generated using a simple approach, they are "random enough" that when combined with a SHA2-256 hashing algorithm and a user-supplied password, the amount of work necessary to break the hash raises the bar beyond what is likely to be worthwhile for potential attackers.
Keep in mind, all we're trying to do is make the original password harder to guess. Turning any password of any length into a password of original length plus forty pseudo-random digits of sixty possible characters is very effective in that regard.
It should be noted that the salt used in protecting passwords of user accounts on most operating systems has lower entropy, and no better random generator than what is used in this module. Using this module in a well-designed user login should cross one item off the list of plausable attack vectors.
AUTHOR
David Oswald, <davido at cpan.org>
BUGS
Please report any bugs or feature requests to bug-password-saltsha at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Password-SaltSha. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Password::SaltSha
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
GitHub
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
LICENSE AND COPYRIGHT
Copyright 2012 David Oswald.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.