13

I would like to compute the bcrypt hash of my password.

Is there an open source command line tool that would do that ?

I would use this hash in the Syncthing configuration file (even if I know from here that I can reset the password by editing the config file to remove the user and password in the gui section, then restart Syncthing).

15

You can (ab)use htpasswd from apache-utils package, provided you have version 2.4 or higher.

htpasswd -bnBC 10 "" password | tr -d ':\n'

-b takes the password from the second command argument
-n prints the hash to stdout instead of writing it to a file
-B instructs to use bcrypt
-C 10 sets the bcrypt cost to 10

The bare htpasswd command outputs in format <name>:<hash> followed by two newlines. Hence the empty string for name and tr stripping the colon and newlines.

The command outputs bcrypt with $2y$ prefix, which may be problem for some uses, but can easily be fixed by another sed since the OpenBSD variant using $2a$ is compatible with the fixed crypt_blowfish variant using $2y$.

htpasswd -bnBC 10 "" password | tr -d ':\n' | sed 's/$2y/$2a/'

Link to htpasswd man page: https://httpd.apache.org/docs/2.4/programs/htpasswd.html
Details about bcrypt variants: https://stackoverflow.com/a/36225192/6732096

  • This version has a problem with the BCrypt implementation of Java Spring Security. The password to hash must be terminated with a null character. Spring Security seems to do it correctly. I think htpasswd is not doing this correctly. – k_o_ Apr 12 '18 at 0:49
  • @k_o_: Can you be more specific on "has a problem"? All bcrypt implementations use the null-character terminator. Some, like py-bcrypt have even additional checks to ensure that null-character isn't a part of password. You can check the Apache implementation on GitHub. I'm using htpasswd with the additional sed to populate database records for multiple Spring applications without problems (that's actually how I come to the answer). – Disassembler Apr 12 '18 at 5:29
  • I was assuming that leaving out the null character was a problem of htpasswd to explain the different encodings between Spring and htpasswd. The output from bcrypt using the other answer's Python approach was producing the same results like in Spring, but htpasswd was not. Maybe also my htpasswd version is quite old, I think the binary was not updated since 2 years. – k_o_ Apr 12 '18 at 21:13
11

You can use a Python library. On my Fedora system I did:

sudo dnf search bcrypt

(the sudo is just to avoid wasting space for a user dnf cache) and from the result can see there is a Python2 and Python3 package:

py-bcrypt.x86_64 : Python bindings for OpenBSD's Blowfish password hashing code
python3-py-bcrypt.x86_64 : Python 3 bindings for OpenBSD's Blowfish password hashing code

Install the Python2 version and list the files in the package:

sudo dnf install py-bcrypt.x86_64
rpm -ql py-bcrypt.x86_64

This shows there is a file /usr/lib64/python2.7/site-packages/bcrypt/__init__.py so I can get the documentation with

pydoc bcrypt

This shows me enough to write the following command which will hash the string "password":

$ python -c 'import bcrypt; print(bcrypt.hashpw("password", bcrypt.gensalt(log_rounds=10)))'
$2a$10$vWFRZgbOx6RKOKYxCTtyWuMJM60E90Vdm/.0nj.X/o3dYUxvQ/2Dm

For later versions of bcrypt use rounds= instead of log_rounds=.

  • 2
    +1. FTR you don't need sudo to run dnf search, it works fine as a standard user. – Stephen Kitt Sep 6 '16 at 7:22
  • 1
    As of April 2018 the parameter log_rounds seems to have changed to rounds making it python -c 'import bcrypt; print(bcrypt.hashpw("password", bcrypt.gensalt(rounds=10)))'. – HorstKevin Apr 11 '18 at 8:42
2

Additional to @Disassembler's answer:

  • it's not a good idea to pass passwords in from the command line (as the password could be viewable with ps)
  • 15 is a good balance for complexity / password generation speed

Wrapper script for htpasswd & bcrypt:

#!/bin/sh

## bcrypt passwd generator ##
#############################
CMD=$(which htpasswd 2>/dev/null)
OPTS="-nBC 15"
USERNAME=$1

usage() {
        local script=$(basename $0)
        cat <<EOF
$script: Generate Bcrypt Hashed Passwords using htpasswd

Usage: $script username
EOF
        exit 1
}

check_config() {
    if [ -z $CMD ]; then
        printf "Exiting: htpasswd is missing.\n"
        exit 1
    fi

    if [ -z "$USERNAME" ]; then
            usage
    fi
}

check_config $USERNAME
printf "Generating Bcrypt hash for username: $USERNAME\n\n"
$CMD $OPTS $USERNAME
exit $?
  • 1
    And unless you start the command line with a space, the password will go to your shell history (an file that is probably not encrypted). – Gabriel Devillers May 15 '18 at 13:32
  • @GabrielDevillers yup, same here. I added "-i" to OPTS and "" to the 2nd-to-last line. – towi Nov 21 '18 at 14:09
  • for BASH & mySQL history for the root user it's a good idea to create a symbolic link to /dev/null. – Stuart Cardall Nov 21 '18 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.