Calcular bcrypt hash desde la línea de comando

17

Me gustaría calcular el hash de bcrypt de mi contraseña.

¿Existe una herramienta de línea de comandos de código abierto que haga eso?

Usaría este hash en el archivo de configuración de Syncthing (incluso si sé desde aquí que puedo restablecer la contraseña editando el archivo de configuración para eliminar el usuario y la contraseña en la sección de la interfaz gráfica de usuario, luego reiniciar Syncthing).

Gabriel Devillers
fuente

Respuestas:

25

Puede (ab) usarlo htpasswddesde el paquete apache-utils , siempre que tenga la versión 2.4 o superior.

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

-btoma la contraseña del segundo argumento de comando,
-nimprime el hash en stdout en lugar de escribirlo en un archivo, le
-Bindica que use bcrypt
-C 10establece el costo de bcrypt en 10

El comando bare htpasswd sale en formato <nombre>: <hash> seguido de dos líneas nuevas. De ahí la cadena vacía para el nombre y la treliminación de los dos puntos y las nuevas líneas.

El comando genera bcrypt con $2y$prefijo, que puede ser un problema para algunos usos, pero puede ser reparado fácilmente por otro sedya que la variante de OpenBSD que usa $2a$es compatible con la variante de crypt_blowfish que usa $2y$.

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

Enlace a la página de manual de htpasswd: https://httpd.apache.org/docs/2.4/programs/htpasswd.html
Detalles sobre las variantes de bcrypt: /programming//a/36225192/6732096

Desensamblador
fuente
Esta versión tiene un problema con la implementación BCrypt de Java Spring Security. La contraseña para el hash debe terminarse con un carácter nulo. Spring Security parece hacerlo correctamente. Creo que htpasswd no está haciendo esto correctamente.
k_o_
@k_o_: ¿Puede ser más específico sobre "tiene un problema"? Todas las implementaciones de bcrypt usan el terminador de caracteres nulos. Algunos, como py-bcrypt, tienen incluso verificaciones adicionales para garantizar que el carácter nulo no sea parte de la contraseña. Puede verificar la implementación de Apache en GitHub . Estoy usando htpasswd con el sed adicional para llenar registros de bases de datos para múltiples aplicaciones Spring sin problemas (así es como llegué a la respuesta).
Desensamblador
Supuse que dejar de lado el carácter nulo era un problema de htpasswd para explicar las diferentes codificaciones entre Spring y htpasswd. El resultado de bcrypt usando el enfoque de Python de la otra respuesta estaba produciendo los mismos resultados que en Spring, pero htpasswd no. Quizás también mi versión htpasswd es bastante antigua, creo que el binario no se actualizó desde hace 2 años.
k_o_
11

Puedes usar una biblioteca de Python. En mi sistema Fedora hice:

sudo dnf search bcrypt

(el sudo es solo para evitar el desperdicio de espacio para un caché dnf de usuario) y del resultado se puede ver que hay un paquete Python2 y 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

Instale la versión de Python2 y enumere los archivos en el paquete:

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

Esto muestra que hay un archivo /usr/lib64/python2.7/site-packages/bcrypt/__init__.pypara que pueda obtener la documentación con

pydoc bcrypt

Esto me muestra lo suficiente como para escribir el siguiente comando que picará la cadena "password":

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

Para versiones posteriores de bcryptuso en rounds=lugar de log_rounds=.

meuh
fuente
2
+1. FTR que no necesita sudoejecutar dnf search, funciona bien como usuario estándar.
Stephen Kitt
1
A partir de abril de 2018, el parámetro log_roundsparece haber cambiado para roundshacerlo python -c 'import bcrypt; print(bcrypt.hashpw("password", bcrypt.gensalt(rounds=10)))'.
HorstKevin
4

Adicional a @Disassemblerla respuesta de:

  • no es una buena idea pasar las contraseñas desde la línea de comandos (ya que la contraseña podría verse con ps)
  • 15 es un buen equilibrio para la complejidad / velocidad de generación de contraseña

Script de envoltura para 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 $?
Stuart Cardall
fuente
1
Y a menos que comience la línea de comando con un espacio, la contraseña irá a su historial de shell (un archivo que probablemente no esté encriptado).
Gabriel Devillers
@GabrielDevillers sí, lo mismo aquí. Agregué "-i" a OPTS y "" a la penúltima línea.
Towi
para el historial de BASH y mySQL para el rootusuario, es una buena idea crear un enlace simbólico /dev/null.
Stuart Cardall el
1
Con respecto al comentario de @ GabrielDevillers, quizás valga la pena mencionar que agregar un espacio al inicio no siempre oculta un elemento del historial de shell, depende del shell y la configuración.
temblor