# NAME
App::bmkpasswd - bcrypt-capable mkpasswd(1) and exported helpers
# SYNOPSIS
## From Perl:
use App::bmkpasswd -all;
my $bcrypted = mkpasswd($passwd);
say 'matched' if passwdcmp($passwd, $bcrypted);
## From a shell:
bmkpasswd --help
# Generate bcrypted passwords:
bmkpasswd
# Defaults to work cost factor '08':
bmkpasswd --workcost='06'
# SHA requires Crypt::Passwd::XS or a recent libc:
bmkpasswd --method='sha512'
# Compare a hash:
bmkpasswd --check=HASH
# Check hash generation times:
bmkpasswd --benchmark
# DESCRIPTION
**App::bmkpasswd** is a bcrypt-enabled `mkpasswd` implementation.
Helper functions are also exported for use in other applications; see
["EXPORTED"](#exported).
[Crypt::Bcrypt::Easy](
https://metacpan.org/pod/Crypt::Bcrypt::Easy) provides an easier bcrypt-specific
programmatic interface for Perl programmers.
See `bmkpasswd --help` for command-line usage information.
Uses [Crypt::Eksblowfish::Bcrypt](
https://metacpan.org/pod/Crypt::Eksblowfish::Bcrypt) for bcrypted passwords.
Bcrypt leverages a work-cost factor allowing hash generation
to become configurably slower as computers get faster, thereby
impeding brute-force hash generation attempts.
See [
http://codahale.com/how-to-safely-store-a-password/](
http://codahale.com/how-to-safely-store-a-password/) for more
on why you ought to be using bcrypt or similar "adaptive" techniques.
**SHA-256** and **SHA-512** are supported if available. SHA support requires
either [Crypt::Passwd::XS](
https://metacpan.org/pod/Crypt::Passwd::XS) or a system crypt() that can handle SHA (such as
glibc-2.7+ or modern FreeBSD builds).
Uses [Bytes::Random::Secure::Tiny](
https://metacpan.org/pod/Bytes::Random::Secure::Tiny) to generate random salts. Strongly-random salts
can also be enabled; see ["mkpasswd"](#mkpasswd).
# EXPORTED
[Crypt::Bcrypt::Easy](
https://metacpan.org/pod/Crypt::Bcrypt::Easy) provides an easier programmatic interface, if you're
only interested in generating bcrypt passwords. If you'd like to make use of
other password types, you can use the exported **mkpasswd** and **passwdcmp**
functions:
# Import selectively:
use App::bmkpasswd 'mkpasswd', 'passwdcmp';
# Or import all functions:
use App::bmkpasswd -all;
This module uses [Exporter::Tiny](
https://metacpan.org/pod/Exporter::Tiny) to export functions. This provides for
flexible import options. See the [Exporter::Tiny](
https://metacpan.org/pod/Exporter::Tiny) docs for details.
## passwdcmp
Compare a password against a hash.
if ( passwdcmp($plaintext, $crypted) ) {
## Successful match
} else {
## Failed match
}
**passwdcmp** will return the hash if it is a match; otherwise, `undef`
is returned. (This is an API change in `v2.7.1`; prior versions return
an empty list on failure.)
## mkpasswd
my $crypted = mkpasswd($passwd);
my $crypted = mkpasswd($passwd, $type);
my $crypted = mkpasswd($passwd, 'bcrypt', $cost);
my $crypted = mkpasswd($passwd, $type, $cost, $strongsalt);
my $crypted = mkpasswd( $passwd =>
+{
type => $type,
cost => $cost,
strong => $strongsalt,
saltgen => $saltgenerator,
}
);
Generate hashed passwords.
By default, generates a bcrypted passwd with work-cost 08:
$bcrypted = mkpasswd($passwd);
A different work-cost can be specified for bcrypt passwds:
$bcrypted = mkpasswd($passwd, 'bcrypt', '10');
SHA-256 and SHA-512 are supported, in which case the work-cost value is ignored:
$crypted = mkpasswd($passwd, 'sha256');
$crypted = mkpasswd($passwd, 'sha512');
If a fourth boolean-true argument is specified, a strongly-random salt is
generated. This requires spare entropy, and will block if entropy-starved:
$crypted = mkpasswd($passwd, 'bcrypt', '08', 'strong');
$crypted = mkpasswd($passwd, 'sha512', 0, 'strong');
Options can be passed as a HASH, instead. This also lets you pass in a salt
generator coderef:
$crypted = mkpasswd( $passwd => +{
type => 'bcrypt',
cost => '10',
strong => 0,
saltgen => $saltgenerator,
}
);
The salt generator is passed the type (one of: `bcrypt`, `sha`, `md5`) and
the value of the **strong** option (default false).
my $saltgenerator = sub {
my ($type, $strongsalt) = @_;
if ($type eq 'bcrypt') {
# ...
} elsif ($type eq 'sha') {
# ...
} else {
die "Don't know how to create a salt for type '$type'!"
}
};
Most people want random salts, in which case the default salt generator
should be fine.
See ["mkpasswd\_forked"](#mkpasswd_forked) if your application loads this module before forking
or creating threads that generate passwords.
## mkpasswd\_available
my @available = mkpasswd_available;
if ( mkpasswd_available('sha512') ) { ... }
Given no arguments, returns the list of available hash types.
Given a type (see ["mkpasswd"](#mkpasswd)), returns boolean true if the method is available. ('bcrypt' is
always available.)
## mkpasswd\_forked
# After a fork / new thread is created:
mkpasswd_forked;
To retain secure salts after forking the process or creating a new thread,
it's advisable to either only load this module after creating the new process
or call **mkpasswd\_forked** in the new process to reset the random seeds used
by salt generators.
Added in `v2.6.1`.
# AUTHOR
Jon Portnoy <
[email protected]>