¿Usar SHA-256 para preprocesar la contraseña antes de bcrypt?

20

Me gustaría permitir que los usuarios de mi aplicación web tengan contraseñas largas, si así lo desean. Hoy me di cuenta de la limitación de la longitud de la contraseña de bcrypt (72 caracteres, el resto está truncado).

¿Sería seguro para mí hacer lo siguiente? Estoy usando PHP.

Implementación actual:

password_hash($password, PASSWORD_BCRYPT, $options);

Implementación en cuestión:

password_hash(hash('sha256', $password), PASSWORD_BCRYPT, $option);

¿Cuáles son los inconvenientes de la implementación en cuestión?

No soy un experto en criptografía, por favor avise.

¿La implementación en cuestión limitará la longitud de la contraseña que un usuario puede usar? Si es así, ¿cuál será el límite?

    
pregunta Jay 14.02.2017 - 10:36
fuente

3 respuestas

24

En general, esto estará bien. Es incluso un método bastante recomendable para permitir contraseñas de longitud arbitraria en bcrypt.

Matemáticamente, ahora está utilizando bcrypt en una cadena de 64 caracteres, donde hay 2 ^ 256 valores posibles (SHA-256 proporciona una salida de 256 bits, que normalmente se representa como una cadena hexadecimal de 64 caracteres). Incluso si alguien pre-calculara las contraseñas comunes en SHA-256, necesitarían ejecutarlas a través de bcrypt para encontrar cuál era la entrada real para un hash dado.

El principal inconveniente potencial son las fallas en la implementación: si alguna vez almacenas los valores SHA-256, son relativamente rápidos de romper, por lo que un atacante no tendría que dedicar el esfuerzo para romper los valores de bcrypt.

Se seguiría recomendando mantener un recuento de iteraciones suficientemente alto para el paso bcrypt, esto no debería tener ningún efecto especialmente perjudicial en el tiempo de procesamiento, pero hace que los ataques de fuerza bruta sean mucho más difíciles.

Consulte Pre-hash de la contraseña antes de aplicar bcrypt para evitar restringir la longitud de la contraseña para el caso general.

    
respondido por el Matthew 14.02.2017 - 10:46
fuente
11

Su implementación sugerida es segura. Sin embargo, tenga cuidado de documentar su uso especial de la función.

Tenga en cuenta que password_hash truncará la contraseña en el primer byte NULL, por lo que NO debe usar la opción $raw_output=true de la función hash .

    
respondido por el A. Hersean 14.02.2017 - 10:53
fuente
4

No lo hagas, estás limitando la fortaleza de tu clave a mucho menos de lo que solo puede aceptar bcrypt.

Utilice este enfoque en su lugar (pseudocódigo no válido de PHP):

if length($password) > 72 bytes
then
    $hash = sha256($password)
    $password = concat(substring($password, 320 bits), base255encode($hash))
end if
bcrypt($password)

De esta manera, las contraseñas entre 256 y 576 bits conservan su entropía completa, y las contraseñas de más de 576 bits utilizan no solo los 256 bits del hash, sino la mayor parte de la entropía original que puede coincidir con el hash.

Es discutible si el hash debe hacerse a través de toda la contraseña, o solo la porción más allá de los 320 bits que reemplaza el hash. Dudo seriamente que haga alguna diferencia cuando hayas elegido un hash criptográfico con buenas propiedades.

El paso base255encode evita que un byte NUL finalice la clave antes, como advirtió @ a-hersean.

    
respondido por el Ben Voigt 14.02.2017 - 21:10
fuente

Lea otras preguntas en las etiquetas