# 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]>