Saltar al contenido

¿Cuál es la razón específica para preferir bcrypt o PBKDF2 sobre SHA256-crypt en los hash de contraseña?

Solución:

La razón principal para usar una función de hash de contraseña específica es hacer la vida más difícil a los atacantes o, más exactamente, evitar que hagan su propia vida más fácil (en comparación con la del defensor). En particular, el atacante puede querer calcular más hashes por segundo (es decir, probar más contraseñas por segundo) con un presupuesto dado usando una GPU.

SHA-256, en particular, se beneficia mucho de su implementación en una GPU. Por lo tanto, si usa SHA-256-crypt, los atacantes tendrán más ventaja que si usa bcrypt, que es difícil de implementar de manera eficiente en una GPU.

Vea esta respuesta para una discusión sobre bcrypt vs PBKDF2. Aunque SHA-256-crypt no es PBKDF2, es lo suficientemente similar en su comportamiento de rendimiento en la GPU, por lo que se aplican las mismas conclusiones.

El caso de SHA-512 es un poco menos claro porque las GPU existentes son mucho mejores para usar enteros de 32 bits que para 64 bits, y SHA-512 usa principalmente operaciones de 64 bits. Todavía se espera que la GPU moderna permita más hashes por segundo que la CPU (para un presupuesto dado) con SHA-512-crypt, que nuevamente apunta a bcrypt como la mejor opción.

La familia de hashes SHA-2 fue diseñada para ser rápida. BCrypt fue diseñado para ser lento. Ambos se consideran robustos. Con suficientes rondas o factor de trabajo, cualquiera puede tomar más tiempo que el otro, pero me inclinaría hacia el que estaba diseñado ser lento. (si la carga del servidor es un problema, el factor de trabajo es ajustable)

Además, me inclinaría por BCrypt porque generalmente es una implementación compilada (C o C ++).

El SHA de múltiples rondas se puede implementar fácilmente en un lenguaje de alto nivel, al menos para la iteración, si no también para el hash en sí. Los lenguajes de alto nivel son menos eficientes para las operaciones matemáticas básicas, lo que reduce la cantidad de rondas que su hardware de producción puede completar por milisegundo.

Si bien ambos algoritmos se pueden implementar en lenguajes de alto o bajo nivel, o en un híbrido; en BCrypt las opciones disponibles dictan que usted es más probabilidades de aterrizar en una implementación eficiente. (te pone en un campo de juego más parejo con el atacante)

En lo que respecta a su ejemplo específico del /etc/shadow archivo, es probable que solo esté en algoritmos de bajo nivel (eficientes) de cualquier manera. (SHA o BCrypt) En este ejemplo, le sugiero que consulte la documentación del sistema operativo para optimizar las rondas (factor de trabajo) basado en la velocidad del hardware -vs- qué tan fuerte le gustaría que fuera el hash.

scrypt (con un factor de trabajo lo suficientemente grande) tiene el beneficio adicional de tener requisitos adicionales de RAM / memoria (no solo CPU), lo que lo hace más Resistente a la GPU que SHA, BCrypt o PBKDF2.

Editar: Gracias a Thomas por señalar que BCrypt es más resistente a la GPU que SHA-2, y que SHA-2 y PBKDF2 son prácticamente equivalentes en este sentido.

Nota: Estoy mirando esta pregunta después de que se realizó esta edición y la tengo en cuenta:

Nota: Me refiero específicamente a los hash de contraseña de múltiples rondas descritos por los documentos vinculados y marcados con los códigos $ 5 $ y $ 6 $ en hash de cripta, ni una sola ronda de las funciones de hash SHA256 o SHA512 simples.


Mirando el largo algoritmo de 22 pasos en este enlace que proporcionó, prefiero darle la vuelta a una pregunta: ¿por qué prefiere usar esto en lugar de PBKDF2 con HMAC-SHA2? Porque, al menos tal como se presenta:

  • La definición de PBKDF2 parece mucho más simple. Esto se debe a que es más modular: difiere la mayor parte de su trabajo a una función pseudoaleatoria suministrada externamente. Esto normalmente se instancia con HMAC, que a su vez difiere la mayor parte de su trabajo a una función hash externa como SHA-1 o SHA-2.
  • Esto significa que la seguridad de PBKDF2 debería ser más fácil de analizar.

Por el contrario, el algoritmo en el documento que proporciona enumera un montón de pasos cuya motivación es más difícil de entender. Por ejemplo:

11. For each bit of the binary representation of the length of the
    password string up to and including the highest 1-digit, starting
    from to lowest bit position (numeric value 1):

    a) for a 1-digit add digest B to digest A

    b) for a 0-digit add the password string

    NB: this step differs significantly from the MD5 algorithm.  It
    adds more randomness.

¿Agrega más aleatoriedad? ¿Como hace esto? ¿Por qué existe este paso en absoluto? ¿SHA-2 no agrega suficiente aleatoriedad? Si SHA-2 no es lo suficientemente aleatorio, ¿por qué usarlo en primer lugar? ¿Y no introduce este paso ramificación dependiente del secreto en el algoritmo, lo que plantea la cuestión de posibles ataques de tiempo en su contra?

De ninguna manera estoy diciendo que los algoritmos que enlazas sean inseguros. Es solo que:

  • El factor de trabajo que introducen se reduce a lo mismo que haría PBDKF2 – HMAC-SHA2 (una gran cantidad de iteraciones SHA2);
  • Se ven muy similares a lo que tendrías si desenrollaras una implementación de PBKDF2-HMAC-SHA2, pero con una complejidad adicional cuyo propósito no entiendo;
  • Entonces al menos como se presenta en esos documentos, Me resulta más difícil ganar confianza en su diseño que en PBKDF2.

EDITAR: Después de escribir todo esto, fui e investigué un poco sobre este algoritmo para intentar comprenderlo mejor. Primero, a partir de los enlaces de “descripción” y “especificación” de la pregunta, nos enteramos de que el algoritmo se derivó de uno más antiguo basado en MD5 mediante modificaciones relativamente menores.

Este antiguo algoritmo basado en MD5 parece el que Poul-Henning Kamp escribió para FreeBSD-2.0 en 1994, que ya no considera seguro. En el primer enlace (donde cuenta la historia de la función), menciona que glibc también adoptó su función. También se vincula al artículo de 1999 de Provos y Mazières sobre bcrypt y menciona que expresó cierta desaprobación y, curiosamente, destacaron el mismo paso que me llamó la atención anteriormente:

MD5 cripta hash la contraseña y la sal en varias combinaciones diferentes para ralentizar la velocidad de evaluación. Algunos pasos en el algoritmo hacen que sea dudoso que el esquema haya sido diseñado desde un punto de vista criptográfico; por ejemplo, la representación binaria de la longitud de la contraseña en algún punto determina qué datos tienen hash, por cada bit cero el primer byte de la contraseña y para cada bit establecido, el primer byte de un cálculo hash previo.

Pero creo que esto explica la motivación de las funciones más nuevas por las que preguntas: son una modificación mínima de una función anterior que es anterior a la mayoría de las funciones modernas de hash de contraseñas, cuyo diseño ha sido cuestionado pero probablemente no esté fundamentalmente roto. simplemente inútilmente complejo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *