# 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](https://metacpan.org/pod/Bytes::Random::Secure) 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 <avenj@cobaltirc.org>