The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

bcrypt - A command-line tool to deal with bcrypt password hashing

SYNOPSIS

Run this from the command line. By default, it reads one line of standard input to get the password. This way the password doesn't show up in your shell's history:

        $ bcrypt
        Reading password on standard input...
        Hello World
        $2b$12$yQePGL/7.u6mVY8tt6fqTO08hQEc2qdWQ..FehvCwBIgMxzM0ULkq

Control the various inputs:

        $ bcrypt --cost 10 --salt abcdef0123456789 --type 2a
        Reading password on standard input...
        Hello World
        $2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu

To check a password against a hash, use --compare. Since the hashed value has $, which is a shell special character in various shells, quote the value:

        $ perl script/bcrypt --compare '$2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu' <<<"Hello World"
        Reading password on standard input...
        Hello World
        Match

In a program, load the program as a module and call run with the same strings you'd use on the command line. The return value of run is the exit status:

        require '/path/to/bcrypt';

        my $exit_status = App::bcrypt::run( @command_line_strings );
        exit $exit_status;

DESCRIPTION

Options

  • --compare - the hash to compare to the password

  • --cost, -c - the cost factor, which should be between 5 and 31, inclusively. This is the exponent for a power of two, so things get slow quickly (default: 12)

  • --debug, -d - turn on debugging (default: off)

  • --eol, -e - the string to add to the end of the hash on output (default: newline)

  • --help, -h - show the documentation and exit. This takes precedence over all other options besides --update-modules and --version.

  • --no-eol, -n - do not add anything to the end of the line (default: off)

  • --password, -p - the password to hash or to compare. But, it's probably better to send it through standard input if you are using this as a command-line program and not a library.

  • --quiet, -q - suppress information messages (default: off)

  • --salt, -s - the salt to use. This is a string the should encode to 16-octet UTF-8 (default: random string)

  • --type, -t - the Bcrypt type, which is one of 2a, 2b (default), 2x, or 2y

  • --update-modules - use cpan(1) to update or install all the Perl modules this program needs. This takes precedence over all other options.

  • --version, -v - show the version. With --debug, this shows extra information about the Perl bits. This option takes precedence over all others except --update-modules.

Environment

If these environment variables are set, they are used as the default values when you do not specify a value through the command line options:

  • BCRYPT_COST

  • BCRYPT_EOL

  • BCRYPT_NO_EOL

  • BCRYPT_QUIET

  • BCRYPT_SALT

  • BCRYPT_TYPE

Exit values

  • 0 - Success in either making the new hash, or that the hash and password match for --compare

  • 1 - The hash and password for --compare do not match

  • 2 - Invalid input

Examples

Install the modules using cpan if you've dropped this file into a system:

        $ bcrypt --update-modules

Create a password with the defaults:

        $ bcrypt
        Reading password on standard input...
        Hello World

Same thing, but without the extra output:

        $ perl script/bcrypt -q
        Hello World
        $2b$12$IqR8.HcodAzvngql3qDw2upnUrjj9HSxutWCgPrUsga0gm7AvTOUu

By default, there's a newline at the end of the hash because it's a normal output line, but you can remove that with --no-eol. First, normally:

        $ bcrypt -q | hexdump -C
        Hello World
        00000000  24 32 62 24 31 32 24 35  4b 63 68 65 4f 6d 65 48  |$2b$12$5KcheOmeH|
        00000010  61 67 52 62 77 2f 4a 57  70 79 54 55 65 73 70 39  |agRbw/JWpyTUesp9|
        00000020  67 76 41 58 78 32 66 6e  79 6e 41 33 2f 6b 75 35  |gvAXx2fnynA3/ku5|
        00000030  6a 43 50 4a 7a 70 5a 38  39 47 58 65 0a           |jCPJzpZ89GXe.|
        0000003d

Now, notice the lack of the 0a at the end:

        $ bcrypt -q --no-eol | hexdump -C
        Hello World
        00000000  24 32 62 24 31 32 24 4d  36 67 2e 54 64 7a 48 49  |$2b$12$M6g.TdzHI|
        00000010  44 58 52 30 73 33 66 2f  66 57 74 74 4f 61 54 70  |DXR0s3f/fWttOaTp|
        00000020  34 2f 7a 57 5a 47 63 44  76 56 63 45 6d 6a 49 4e  |4/zWZGcDvVcEmjIN|
        00000030  50 79 4c 79 41 74 48 62  71 56 79 75              |PyLyAtHbqVyu|
        0000003c

Choose your own settings. The value for --salt should be a string that will UTF-8 encode to exactly 16 octets. Care with --cost because that's a power of 2:

        $ bcrypt --type 2a --cost 30 --salt abcdef0123456789
        Reading password on standard input...
        Hello World
        $2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu

Compare a hash to a password supplied on standard input:

        $ bcrypt --compare '$2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu'
        Reading password on standard input...
        Hello Worldd
        Does not match

Do the same thing quietly, but use the exit value to figure out what happened. This bad password has an extra d:

        $ bcrypt --quiet --compare '$2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu'
        Hello Worldd
        $ echo $?
        1

This password is the right one:

        $ bcrypt --quiet --compare '$2a$10$WUHhXETkKBCwKxOzLha2MOVweNmcwXQeoLR9jJlmEcl7rMR2ymqNu'
        Hello World
        $ echo $?
        0

SEE ALSO

  • Crypt::Bcrypt (which this program uses)

  • Mojolicious::Plugin::Bcrypt

  • Mojolicious::Command::bcrypt

  • https://github.com/shoenig/bcrypt-tool, a Golang tool

SOURCE AVAILABILITY

This source is in Github:

        http://github.com/briandfoy/app-bcrypt

AUTHOR

brian d foy, <brian d foy>

COPYRIGHT AND LICENSE

Copyright © 2023, brian d foy, All Rights Reserved.

You may redistribute this under the terms of the Artistic License 2.0.