从命令行计算bcrypt哈希


Answers:


27

您可以(ap)htpasswdapache-utils软件包中使用,前提是您拥有2.4或更高版本。

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

-b从第二个命令参数获取密码,将
-n哈希值打印到stdout,而不是将其写入文件,
-B指示使用bcrypt
-C 10将bcrypt 成本设置为10

htpasswd裸命令以<name>:<hash>格式输出,后跟两个换行符。因此,将使用空字符串作为名称,tr并删除冒号和换行符。

该命令输出带$2y$前缀的bcrypt ,这在某些用途中可能会出现问题,但sed由于使用的OpenBSD变体$2a$与的固定crypt_blowfish变体兼容,因此可能容易被另一个使用固定$2y$

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

链接到htpasswd手册页:https
://httpd.apache.org/docs/2.4/programs/htpasswd.html有关bcrypt变体的详细信息:https : //stackoverflow.com/a/36225192/6732096


该版本的Java Spring Security的BCrypt实现存在问题。哈希密码必须以空字符结尾。Spring Security似乎正确地做到了。我认为htpasswd无法正确执行此操作。
k_o_

@k_o_:您能否更具体地说明“有问题”?所有bcrypt实现均使用空字符终止符。诸如py-bcrypt之类的工具甚至还进行了其他检查,以确保空字符不是密码的一部分。您可以在GitHub上检查Apache实现。我正在使用htpasswd和附加的sed来填充多个Spring应用程序的数据库记录,而不会出现问题(这实际上就是我的答案)。
拆机

我假设忽略空字符是htpasswd的问题,以解释Spring和htpasswd之间的不同编码。使用其他答案的Python方法的bcrypt的输出产生的结果与Spring相同,但htpasswd却没有。也许我的htpasswd版本很旧,我认为该二进制文件自2年以来未更新。
k_o_

11

您可以使用Python库。在我的Fedora系统上,我做了:

sudo dnf search bcrypt

(sudo只是为了避免浪费用户dnf缓存的空间),从结果可以看到有一个Python2和Python3包:

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

安装Python2版本并在包中列出文件:

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

这表明有一个文件,/usr/lib64/python2.7/site-packages/bcrypt/__init__.py所以我可以通过

pydoc bcrypt

这足以让我写出下面的命令来对字符串进行哈希处理"password"

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

供更高版本bcrypt使用rounds=代替log_rounds=


2
+1。FTR不需要sudo运行dnf search,它可以作为标准用户正常运行。
斯蒂芬·基特

1
截至2018年4月,该参数log_rounds似乎已更改为roundsmake python -c 'import bcrypt; print(bcrypt.hashpw("password", bcrypt.gensalt(rounds=10)))'
HorstKevin

4

@Disassembler的答案的补充:

  • 从命令行传递密码不是一个好主意(因为可以使用来查看密码ps
  • 15 平衡复杂性/密码生成速度

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 $?

2
而且,除非您在命令行中以空格开头,否则密码将进入您的Shell历史记录(该文件可能未加密)。
加布里埃尔·德维勒

@GabrielDevillers是的,这里也是。我在OPTS中添加了“ -i”,在倒数第二行中添加了“”。
towi

对于用户的BASH和mySQL历史记录,root最好创建到的符号链接/dev/null
Stuart Cardall '18

1
关于@GabrielDevillers的评论,也许值得一提的是,在开头添加一个空格并不总是从shell历史记录中隐藏一个项目-取决于shell和设置。
tremby
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.