Authen::Passphrase::SaltedSHA512 - Safe, Sane, and Simple passphrase salting, hashing and authentication.
Version 0.07
This module is a subclass of Authen::Passphrase::SaltedDigest. It adds two features to make your life a little easier and safer. First, it simplifies the user interface by selecting reasonable (and secure) defaults. Second, in generating salt, it uses the high quality, CSPRNG provided by Bytes::Random::Secure.
Some examples:
use Authen::Passphrase::SaltedSHA512; # Generate a salt and hash from a passphrase. my $gen = Authen::Passphrase::SaltedSHA512->new( passphrase => 'Sneaky!' ); my $hash = $gen->hash_hex; my $salt = $gen->salt_hex; # Store the hash and the salt in your user database. # Later.... # Challenge a passphrase to authenticate a user login. # First, retrieve the user's hash and salt from your user database. # Then generate a challenge object: my $challenge = Authen::Passphrase::SaltedSHA512->new( salt_hex => $salt, hash_hex => $hash ); # And challenge the passphrase supplied for the current session's login. if( $challenge->match( 'Sneaky!' ) ) { print "You are a winner!\n"; } # Or for the ultimate in ease and simplicity: use Authen::Passphrase::SaltedSHA512 qw( generate_salted_sha512 validate_salted_sha512 ); my ( $salt_hex, $hash_hex ) = generate_salted_sha512( $passphrase ); my $is_valid = validate_salted_sha512( $passphrase, $salt_hex, $hash_hex );
Authen::Passhprase::SaltedSHA512 is designed to simplify the process of generating random salt for, and a salted hash of a user supplied passphrase.
It is also designed to easily authenticate a user supplied passphrase against a given salt and hash.
The presumed use-case is for user authentication where a salt and a password hash will be stored in a database of user logins. The simple interface should fit into a broad range of authentication systems with minimal clutter.
Authen::Passphrase::SaltedSHA512 is a subclass of Authen::Passphrase::SaltedDigest that overrides the constructor to provide reasonable defaults so that you don't have to spend a week reading articles on which algorithm to use, and how to generate a good salt.
The hashing algorithm chosen is the SHA-512 hash function from the SHA-2 family. Currently SHA-512 is a leading edge standard in strong hashing.
The salt generated when creating authentication credentials is a 512 bit random string. The random number generating algorithm used comes from Bytes::Random::Secure. That module uses Math::Random::ISAAC, "...a cryptographically-strong random number generator with no known serious weaknesses." Bytes::Random::Secure obtains its seed using Crypt::Random::Seed. The reason that Bytes::Random::Secure was chosen over other random number generators is because that module has a light-weight dependency chain, a cryptographically strong random number generator, strong seeding (the hardest part of the CSPRNG problem) across a wide variety of platforms, and useful hex output.
By using a 512 bit random salt, a maximum degree of entropy is achieved in the hashes generated by the SHA-512 algorithm. Every time the constructor is called you will get a new random salt, so every user has his own salt. The advantage of using a fresh random salt for each user is that it eliminates the rainbow table attack vector, by guaranteeing that if one user's password is compromised through brute force (or cosmic good luck) all of your other users with their own random salts are still secure.
By selecting secure defaults for hashing algorithm, random number generation, and salt bit-length, much of the guesswork can be eliminated from devising an authentication scheme, and a simpler user interface results.
This is primarily an Object Oriented Interface module. However, for even greater simplicity, a standard functions interface is provided upon request. Nothing is exported by default. By supplying an export list, the following subroutines are available:
generate_salted_sha512
validate_salted_sha512
The following section describes the methods available through the module's Object Oriented interface.
The constructor will create an object that can either be used to generate a salt and a hash for later use, or to challenge a supplied salt and hash by a passphrase supplied to match.
match
Instantiate a salt and hash generator object.
my $auth_gen = Authen::Passphrase::SaltedSHA512->new( passphrase => 'All your base are belong to us.' );
Instantiate a challenge object.
my $challenger = Authen::Passphrase::SaltedSHA512->new( salt_hex => $retrieved_salt, hash_hex => $retrieved_hash );
For passphrase hash and salt generation, you must supply the passphrase parameter. For validation, you must supply either a raw or a hex salt, using the salt or salt_hex parameters, and either a raw or a hex hash, using the hash or hash_hex parameters. These are described below.
passphrase
salt
salt_hex
hash
hash_hex
The salt, as a raw string of bytes. Defaults to the empty string, yielding an unsalted scheme.
The salt, as a string of hexadecimal digits. Defaults to the empty string, yielding an unsalted scheme.
The hash, as a string of bytes.
The hash, as a string of hexadecimal digits.
A passphrase that will be accepted.
You must supply either a passphrase, or a salt and a hash. The salt and the hash may either be supplied as salt => $raw_string and hash => $raw_string or as salt_hex => $hex_digits and hash_hex => $hex_digits. Both the salt and the hash will be 512 bits long, or 128 hex digits.
salt => $raw_string
hash => $raw_string
salt_hex => $hex_digits
hash_hex => $hex_digits
If a passphrase is suppled, a generator object will be created. If some form of salt and hash are supplied, a challenge object will be created.
Returns the 512 bit salt, in raw form (64 bytes).
my $salt = $auth_gen->salt;
Returns the salt, as a string of 128 hexidecimal digits.
my $salt_hash = $auth_gen->salt_hash;
Returns the 512 bit hash, in raw form.
my $hash = $auth_gen->hash;
Returns the hash, as a string of 128 hexidecimal digits.
my $hash_hex = $auth_gen->hash;
Returns true if $passphrase matches against the salt and hash supplied to the constructor, and false otherwise.
$passphrase
if( $challenge->match( $passphrase ) ) { print "Your passphrase has been authenticated.\n"; } else { print "Invalid passphrase.\n", "You have 1.34e154 more tries before exhausing all possible guesses.\n", "Happy hunting!\n"; }
Returns the digest algorithm, which will always be SHA-512.
SHA-512
This section describes the subroutines used in this module's standard (non-OO) interface.
Accepts a $passphrase parameter, and returns a list containing a hex representation of a random salt, and of the hash.
my( $salt_hex, $hash_hex ) = generate_salted_sha512( 'Groovy Password' );
Accepts parameters of $passphrase, $salt_hex, and $hash_hex, and returns true if $passphrase authenticates against the given salt and hash.
$salt_hex
$hash_hex
my $is_valid = validate_salted_sha512( 'Groovy Password', $salt_hex, $hash_hex );
While the choice of the SHA-2 SHA-512 function was an easy one, selecting a random number generator for building cryptographically useful salt proved more difficult. Some modules are using one of the Math::Random::MT modules, yet the POD for Math::Random::MT states, "This algorithm has a very uniform distribution and is good for modelling purposes but do not use it for cryptography."
Authen::Passphrase::SaltedDigest could generate random salt, but relies on Data::Entropy to do so. Data::Entropy::Algorithm, by default seems to be constrained by the quality of Perl's seed, which is probably not as secure of a source as should be used. That leads to a search for a better solution.
seed
The list of other possibilities is long, and while many of them might turn out to be reasonable choices, Math::Random::Secure seemed to offer a solution that is secure today, and should continue to follow Best Practices as new trends emerge. The disadvantage is that it is heavy on dependencies. This seems to be the price one has to pay for a really good random source.
Because Authen::Passphrase::SaltedSHA512 is a subclass of Authen::Passphrase::SaltedDigest, the hash and salt generated can also be challenged using Authen::Passphrase::SaltedDigest in place of this module simply by supplying the appropriate defaults to the constructor:
my $apsd = Authen::Passphrase::SaltedDigest->new( algorithm => 'SHA-512', salt => $salt, hash => $hash ); print "You win!\n" if $apsd->match( $passphrase );
By the same token, Authen::Passphrase::SaltedDigest generated hashes are compatible with Authen::Passphrase::SaltedSHA512, if they are generated using the algorithm => 'SHA-512' setting:
algorithm => 'SHA-512'
my $apss = Authen::Passphrase::SaltedSHA512->new( salt => $salt, hash => $hash, ); print "Bingo!\n" if $apss->match( $passphrase );
So if you want a drop-in replacement for Authen::Passphrase::SaltedDigest that defaults to SHA-512 hashing with automatic generation of salts composed of 512 securely-random bits, the changes to your code will be simple.
However, the as_rfc2307 method from Authen::Passphrase::SaltedDigest shouldn't and can't be used within Authen::Passphrase::SaltedSHA512. See the INCOMPATIBILITIES section below for details.
as_rfc2307
This module should install and run on any system that supports Perl from v5.8.0 to the present, and fits easily into authentication plugins such as Mojolicious::Plugin::Authentication.
The as_rfc2307 method of Authen::Passphrase::SaltedDigest doesn't allow for hard coded defaults, and thus, is meaningless in the context of this module. Furthermore, this module doesn't consider the algorithm and random_salt directives in its constructor; it already sets a SHA-512 default and always generates a 512-bit random salt.
algorithm
random_salt
One of the module's dependencies that inherited through Authen::Passphrase may fail to pass its test suite on some Windows systems. The part that fails relates to the random number generator used by Authen::Passphrase. This module uses a different random number generator -- not the one from Authen::Passphrase. You may decide that if a failure to install traces back to a random number generation module for Authen::Passphrase a forced install could still be appropriate.
This module has the following non-core immediate dependencies:
Each of these has its own list of non-core dependencies as well. But it's a well-tested set of dependencies, with broad portability demonstrated by the smoke tests. Most important, we're using not only a cryptographically strong random number generator, but also a strong source to seed the generator.
This module should be installable on most platforms via the traditional CPAN installers, or by unpacking the tarball and repeating the well-known mantra:
make make test make install
As this module subclasses Authen::Passphrase::SaltedDigest, all of the warnings and diagnostic messages produced by that module will be present in this module.
Additional examples are provided in the examples/ folder within the module's build directory.
examples/
Authen::Passphrase
Authen::Passphrase::SaltedDigest
Bytes::Random::Secure
Wikipedia article on SHA-2 (SHA-512)
David Oswald, <davido at cpan.org>
<davido at cpan.org>
Please report any bugs or feature requests to bug-authen-passphrase-saltedsha512 at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Authen-Passphrase-SaltedSHA512. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-authen-passphrase-saltedsha512 at rt.cpan.org
Password protection and authentication is an arms race of sorts. For now, SHA-512 hasn't been broken, and for now, the random number generator used to generate random salt is considered cryptographically sound. However, this module is only one element in what necessarily must be a system-wide approach to robust security.
You can find documentation for this module with the perldoc command.
perldoc Authen::Passphrase::SaltedSHA512
You can also look for information at:
This module's GitHub repository
http://github.com/daoswald/Authen-Passphrase-SaltedSHA512
RT: CPAN's request tracker (report bugs here)
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Authen-Passphrase-SaltedSHA512
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Authen-Passphrase-SaltedSHA512
CPAN Ratings
http://cpanratings.perl.org/d/Authen-Passphrase-SaltedSHA512
Search CPAN
http://search.cpan.org/dist/Authen-Passphrase-SaltedSHA512/
Thanks go to the following individuals for providing input, suggestions, or code:
Matt S. Trout -- Suggested the Authen::Passphrase family as a nice foundation upon which this module could be easily constructed.
M. Aaron Bossert -- Provided some module suggestions that, while ultimately weren't used, started me on path that combined with further research arrived at this destination.
Andrew Main (Zefram) -- Creator of the excellent Authen::Passphrase distribution which this module subclasses.
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.
To install Authen::Passphrase::SaltedSHA512, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Authen::Passphrase::SaltedSHA512
CPAN shell
perl -MCPAN -e shell install Authen::Passphrase::SaltedSHA512
For more information on module installation, please visit the detailed CPAN module installation guide.