# 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