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

60

Sabemos que para reducir la velocidad de descifrado de contraseñas en el caso de una pérdida de la base de datos de contraseñas, las contraseñas se deben guardar solo en un formato hash. Y no solo eso, sino también una función fuerte y lenta con la posibilidad de variar el número de rondas.

A menudo, los algoritmos como PBKDF2 , bcrypt y scrypt se recomiendan para esto, con bcrypt aparentemente obteniendo los votos más altos, por ejemplo aquí , here y here .

Pero, ¿qué pasa con los hash basados en SHA256 y SHA512 implementados en al menos glibc ( description , especificación ) y se usa de forma predeterminada al menos en algunas distribuciones de Linux para cuentas de inicio de sesión regulares. ¿Hay alguna razón para no usarlos, o para preferir bcrypt sobre los hashes basados en SHA-2?

Por supuesto, bcrypt es significativamente más antiguo (1999) y, por lo tanto, más establecido, pero los hashes SHA-2 ya tienen nueve años (2007), y Scrypt es incluso un poco más joven (2009), pero aún parece ser mencionado más a menudo. ¿Es solo una práctica aceptada, o hay alguna otra razón? ¿Hay alguna debilidad conocida en los hashes basados en SHA-2 o alguien ha mirado?

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

He visto la pregunta que está marcada como un posible duplicado de. Las respuestas no mencionan los hashes SHA256-crypt / SHA512-crypt, que es lo que estoy buscando.

    
pregunta ilkkachu 08.08.2016 - 14:21
fuente

5 respuestas

46

La razón principal para usar una función de hash de contraseña específica es hacer que la vida de los atacantes sea más difícil o, más precisamente, evitar que ellos 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 determinado mediante el uso de una GPU.

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

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

El caso de SHA-512 es un poco menos claro porque la GPU existente es mucho mejor en el uso de enteros de 32 bits que en los de 64 bits, y SHA-512 utiliza 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 determinado) con SHA-512-crypt, lo que nuevamente apunta a bcrypt como la mejor opción.

    
respondido por el Thomas Pornin 08.08.2016 - 16:55
fuente
32

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 inclino por el que fue diseñado para ser lento. (Si la carga del servidor es un problema, el factor de trabajo es ajustable)

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

El SHA de múltiples rondas se puede implementar fácilmente en 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 el 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 es más probable que caiga 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 archivo /etc/shadow , es probable que solo esté en algoritmos de bajo nivel (eficiente) de cualquier manera. (SHA o BCrypt) En este ejemplo, sugeriría que consulte la documentación del sistema operativo para optimizar las rondas (factor de trabajo) según la velocidad del hardware -vs- qué tan fuerte le gustaría que sea el hash .

scrypt (con un factor de trabajo suficientemente grande) tiene la ventaja adicional de tener requisitos de RAM / memoria adicionales (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 a este respecto .

    
respondido por el George Bailey 08.08.2016 - 16:50
fuente
5

Nota: Observo esta pregunta después de realizar esta edición y la tengo en cuenta:

  

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

Mirando el largo algoritmo de 22 pasos en este enlace que proporcionó , prefiero invierte una pregunta: ¿por qué preferirías usar esto en lugar de PBKDF2 con HMAC-SHA2? Porque, al menos según lo presentado:

  • La definición de PBKDF2 parece mucho más sencilla. Esto se debe a que es más modular: difiere la mayor parte de su trabajo a una función pseudoaleatoria suministrada externamente. Normalmente se crea una 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.

En contraste, el algoritmo en el documento que proporciona muestra una tonelada 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.

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

No estoy diciendo de ninguna manera que los algoritmos que vinculas son inseguros. Es solo que:

  • El factor de trabajo que introducen se reduce a lo mismo que PBDKF2: HMAC-SHA2 haría (un gran número de iteraciones SHA2);
  • Se ven muy similares a los que tendrías si desenrollases 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 que escribí todo esto, fui e hice un poco de investigación sobre este algoritmo para intentar entenderlo mejor. Primero, de la propia "descripción" de la pregunta y " especificación ", aprendemos que el algoritmo se derivó de uno antiguo basado en MD5 al hacer modificaciones relativamente menores.

Este antiguo algoritmo basado en MD5 aparece 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 enlaza con el artículo de 1999 de Provos y Mazières sobre bcrypt y menciona que desaprobación, y curiosamente destacaron el mismo paso que llamó mi atención arriba :

  

MD5 crypt contiene la contraseña y la sal en varias combinaciones diferentes para disminuir la velocidad de la 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 se hashean, por cada bit cero el primer byte de la contraseña y para cada bit establecido, el primer byte de un cálculo de hash anterior.

Pero creo que esto explica la motivación de las funciones más nuevas sobre las que pregunta: son una modificación mínima de una función más antigua que es anterior a la mayoría de las funciones hash de contraseña modernas, cuyo diseño ha sido cuestionado pero es probable que no sea así. fundamentalmente roto, simplemente sin sentido complejo.

    
respondido por el Luis Casillas 09.08.2016 - 00:50
fuente
3

Bueno, una de las características de bcrypt es que es un algoritmo muy lento. Esta lentitud ofrece una seguridad adicional para los ataques de fuerza bruta. Pero por la misma razón, puede que no sea la mejor solución, por ejemplo, para servidores web muy utilizados, porque aquí una máquina altamente cargada tendrá que hacer ese cálculo pesado en cada inicio de sesión.

Pero mientras tu sistema pueda aceptarlo, ese tiempo adicional en realidad molesta a los atacantes de fuerza bruta.

    
respondido por el Serge Ballesta 08.08.2016 - 15:29
fuente
3

La familia SHA-2 en sí no es necesariamente mala. Por diseño, en realidad no hay fallas de seguridad que hagan que bcrypt o scrypt sean preferibles. Sin embargo, el problema que muchos expertos en seguridad tienen con SHA es que es demasiado rápido y no requiere mucha memoria. En comparación, una función de hashing como scrypt es mucho más lenta y costosa, por así decirlo.

Scrypt requiere una cantidad decente de memoria para calcular. Además de toda esta memoria, y en gran parte como resultado de necesitar tanta memoria, scrypt requiere mucho tiempo de cálculo en comparación con SHA. Esta respuesta del sitio BitCoin Stack Exchange resume las ventajas de scrypt bastante bien: ¿Qué características de scrypt () hacen que Tenebrix sea resistente a la GPU? En esencia, scrypt está diseñado para ser lento y requiere mucha memoria. A las GPU no les gusta eso. Por lo general, las GPU no tienen la capacidad de memoria para almacenar toda la memoria necesaria para el cálculo de scrypt sin tener que recurrir a métodos de bloqueo de ejecución ( donde la GPU bloquea todos los subprocesos porque solo puede recuperar valores de la memoria compartida, uno a uno ), y por lo tanto, las GPU no pueden proporcionar un gran beneficio sobre las CPU en términos de tiempo de procesamiento. Bcrypt es similar.

Bcrypt se ha probado y es verdadero para el hashing de contraseñas. Ha existido durante 17 años, y todavía hace el trabajo. Sin embargo, un día, la tecnología de GPU avanzará hasta el punto en que sea capaz de calcular un cifrado más rápido y más eficiente que una CPU. La tecnología siempre está evolucionando y desarrollándose, por lo que eventualmente sucederá. Cuando llegue ese día, bcrypt ya no será una excelente elección para el hash de contraseñas, y los criptógrafos y los expertos en seguridad necesitarán reemplazar bcrypt con un algoritmo similar que requiere más memoria y más memoria que el bcrypt existente. Tal vez eso sea scrypt, pero quién puede decir. Entonces, ¿por qué SHA está mal visto?

SHA generalmente no se recomienda debido a fallas de seguridad, sino a la velocidad y su capacidad para implementarse en una GPU. Alguien con máquinas / capacidad de computación ilimitadas podría descifrar cualquier tipo de algoritmo de hash, ya sea SHA, bcrypt o scrypt, pero eso es teórico. En la práctica, un atacante no tendrá un número ilimitado de máquinas para tratar de descifrar hashes, y, como resultado, cuanto más pueda ralentizar a ese atacante, más difícil será para él descifrar una contraseña. Hay un límite de presupuesto para todo, y el descifrado de contraseñas no es una excepción. El atacante solo puede descifrar contraseñas tan rápido como lo permita su presupuesto. ( La mejor tecnología que pueden comprar dentro de su presupuesto, el costo de ejecutar esa tecnología (por ejemplo, costos de electricidad), etc. ) Por supuesto, puede implementar varias rondas de SHA para ralentizar severamente a un atacante. , pero ¿por qué no usar simplemente bcrypt en ese punto? Entre otras cosas, a medida que la tecnología de GPU avance en el futuro cercano, deberá agregar más y más rondas / iteraciones a sus cálculos de SHA para reducir la velocidad hasta el punto en que sea más lenta que bcrypt. Sin embargo, a medida que avanza la tecnología de GPU, bcrypt seguirá sin cambios, hasta el punto en que la tecnología de GPU permite que bcrypt se calcule de manera eficiente. Por lo tanto, bcrypt es la opción preferible siempre que sea posible, no porque SHA sea insegura, sino porque SHA es demasiado computacionalmente eficiente.

    
respondido por el Spencer Doak 08.08.2016 - 20:41
fuente

Lea otras preguntas en las etiquetas