¿Por qué no mezclar hashes?

20

Para hacer que los hashes sean más difíciles de localizar mediante hardware especializado, intuitivamente me imagino que mezclar un conjunto de diferentes algoritmos de hash debería proporcionar más fuerza. Para simplificar, asumamos que Hash1 es una cantidad de iteraciones de SHA256 , Hash2 es bcrypt y Hash3 es scrypt :

myhash = Hash1(Hash2(Hash3(0, password, salt), password, salt), password, salt)

Suponiendo que Hash1 , Hash2 y Hash3 toman 1/3 segundos cada uno para calcular en el hardware de un usuario típico, ¿por qué parece preferible usarlo?

myhash = Hash1(Hash1(Hash1(0, password, salt), password, salt), password, salt)

EDITAR: se cambió el formato corto Hash1(Hash1(Hash1(password ^ salt))) , a un formato más preciso Hash1(Hash1(Hash1(0, password, salt), password, salt), password, salt) , para evitar respuestas que solo señalan la mayor cantidad de colisiones con el formato anterior. Las colisiones no son un factor en el hash de la contraseña del usuario siempre que la entropía restante de myhash (~ 256 - x debido a las colisiones, con x cerca de 0) sea sensiblemente más alta que la entropía de la contraseña del usuario. La contraseña de un usuario tiene casi siempre menos de 60 bits de entropía, a menos que sea elegida por un generador de contraseñas.

    
pregunta Peter 12.07.2015 - 17:18
fuente

7 respuestas

11

Me pidieron que hiciera una respuesta a mi comentario, así que aquí va.

Básicamente, dije que los gustos de bcrypt, scrypt y pbkdf2 no son hashes en sí, sino que son KDF (funciones de derivación de claves). Los KDF se basan en algoritmos HMAC, que a su vez se basan en algoritmos de hashing unidireccionales como SHA-256 para generar los valores de resumen del mensaje.

Ya existe una mezcla, agitación y agitación importantes para obtener un valor de un KDF.

Incluso si mezclar la salida de múltiples KDF no debilita la seguridad general, parece probable que no la mejore sustancialmente.

    
respondido por el Craig 12.07.2015 - 23:32
fuente
27

Al intentar hash passwords , el atacante puede Siempre usa el mismo tipo de hardware que el defensor. Lo que intenta el atacante es hacerlo mejor, utilizando un hardware especializado que le permita poner N contraseñas potenciales por menos costo total que si estuviera usando el hardware del defensor. El costo total incluye el costo de comprar el hardware, el costo de desarrollar el software relevante en él y luego el costo de ejecutar el hardware, que básicamente equivale a la electricidad utilizada (para alimentar el hardware y para enfriarlo). Para un atacante serio, el costo de energía domina.

Siempre que hay una operación que el atacante puede hacer más barato que el defensor, el atacante gana. Un punto importante es que el descifrado de contraseñas es un problema vergonzosamente paralelo : por definición, el atacante tiene muchos contraseñas potenciales para probar.

Supongamos que conectas en cascada tres funciones hash distintas Hash1 , Hash2 y Hash3 . Esto significa que el defensor debe tener las tres implementaciones a mano, todas ejecutadas en su servidor. El atacante, por otro lado, puede tener una mejor programación: puede (por ejemplo) capturar un millón de contraseñas potenciales con Hash1 y guardar los resultados en algún búfer; luego cambie el hardware a algo que aplique Hash2 , y ejecútelo sobre el millón de salidas guardadas del paso anterior, ahorrando nuevamente las salidas Hash2 en algún búfer; finalmente cambiando el hardware nuevamente, con Hash3 .

Este tipo de "cambio de hardware" es especialmente relevante cuando se utiliza FPGA : cada "cambio" es una reprogramación del mismo hardware real, y es cuestión de unos pocos segundos como máximo. Al utilizar dicha programación y almacenamiento en búfer, el costo de "cambio" es insignificante.

Esto también se puede usar como canalización: si el atacante creó tres máquinas especializadas, una para Hash1 , una para Hash2 y otra para Hash3 , entonces puede ejecutar Hash1 en la primera contraseña potencial, luego envíe la salida a la máquina que calcula Hash2 . Mientras que la segunda máquina calcula Hash2 , la primera máquina puede calcular Hash1 en otra contraseña potencial. Y así. En la práctica, el atacante puede mantener todas sus máquinas especializadas en plena ocupación en cualquier momento, por lo que se ríe de sus intentos de "aumentar la fuerza".

Además, si hay tres funciones hash distintas para implementar y solo una de ellas puede optimizarse con hardware especializado, entonces el atacante sigue ganando al optimizar esa. Para decir crudamente las cosas, si conectas en cascada bcrypt, scrypt y SHA-256, entonces el atacante usará una PC para las dos primeras y una GPU para la SHA-256, y así evitará aproximadamente 1/3 del costo.

Para resumir, la intuición de que "mezclar un conjunto de algoritmos hash diferentes debería proporcionar una fuerza adicional" es incorrecta. Hace lo contrario. Dicha mezcla aumenta los costos de desarrollo y uso para el defensor, mientras que no ralentiza al atacante (que tiene mucho paralelismo con el que beneficiarse), y aumenta las opciones de optimización del atacante.

(Todo esto se dice sin hablar de cosas prácticas, como el manejo de las sales individuales para todas las funciones en cascada y los peligros de la criptografía hecha en casa).

    
respondido por el Thomas Pornin 12.07.2015 - 18:02
fuente
9

Para copiar mi respuesta a una pregunta similar en progs.SE:

  

el problema con

hash1(hash2(hash3(...hashn(pass+salt)+salt)+salt)...)+salt)
     

es que esto es tan fuerte como la función hash más débil en el   cadena. por ejemplo, si hashn (el hash más interno) da una colisión   toda la cadena de hash dará una colisión ( independientemente de lo que   otros hashes están en la cadena )

     

una cadena más fuerte sería

hash1(hash2(hash3(...hashn(pass+salt)+pass+salt)+pass+salt)...)+pass+salt)
     

aquí evitamos el problema de colisión temprana y generamos esencialmente   una sal que depende de la contraseña para el hash final

     

y si un paso en la cadena choca, no importa porque en el   El siguiente paso es volver a utilizar la contraseña y debe dar un nombre diferente.   resultado para diferentes contraseñas

    
respondido por el ratchet freak 12.07.2015 - 22:27
fuente
6

El uso de diferentes algoritmos hash no le dará más entropía, sino menos. Supongo que ha escuchado la expresión «La seguridad no es más fuerte que el punto más débil», lo mismo se aplica aquí también. La entropía de esto no será más que lo que proporciona el algoritmo más débil.

Pero el hashing de la contraseña con el mismo algoritmo varias veces le dará más seguridad. Pero use un algoritmo hash fuerte pocas rondas en lugar de un algoritmo débil muchas rondas. Ejemplo esto es más seguro:

sha512 ( sha512 ( sha512 ( password + salt )))

Que:

sha1 ( sha1 ( sha1 ( sha1 ( sha1 ( sha1 ( ... sha1 ( password + salt ) ... ))))))

Veo que hay personas que no creen en esto y quieren que lo demuestre. Tomemos un ejemplo. He elegido tres algoritmos de hash, SHA256, SHA1 y MD5.

  • SHA256 produce una salida de 256 bits
  • SHA1 produce una salida de 160 bits
  • MD5 produce una salida de 128 bits

Así que si tenemos:

sha256 ( sha1 ( md5 ( password + salt )));

Primero, la contraseña y el salt se incluyen con el MD5, la salida será de 128 bits, por lo que las posibilidades totales de salida del MD5 son 2 ^ 128. Luego, la suma MD5 se procesa con SHA1, pero no es necesario que tenga todas las posibilidades, solo 2 ^ 128 como salidas MD5. Luego, la suma de SHA1 se procesa con SHA256, pero nuevamente. No es necesario tener todas las posibilidades de SHA256, solo las 2 ^ 128 posibilidades que produce MD5. Entonces, este algoritmo de hash solo puede producir una salida con entropía de 2 ^ 128, como el MD5. Y MD5 tiene múltiples vulnerabilidades, por lo que la fuerza real es inferior a 2 ^ 128.

    
respondido por el BufferOverflow 12.07.2015 - 17:47
fuente
2

La mezcla de hashes generalmente resulta en la seguridad del hash más débil de la cadena, a saber:

  • Primera resistencia en preimagen
  • Segunda resistencia en preimagen
  • resistencia a la colisión

En lugar de mezclar hashes, la potencia de la CPU generalmente se dirige mejor al hashing con más bytes.

En otras palabras, si el hash con dos algoritmos requiere N Joules de trabajo y resulta en menos seguridad, solo use SHA512 en lugar de SHA256 y estará más seguro.

    
respondido por el random65537 12.07.2015 - 17:55
fuente
2

Los hash no deben apilarse; más bien, el resultado de múltiples hashes debe ser XORed juntos. Una primitiva de este tipo (que las XOR juntas unen múltiples funciones hash fuertes y creídas) pueden usarse en el bucle de PBKDF o similar para lograr resultados muy superiores a las funciones hash de apilamiento. Lo que debe tenerse en cuenta en el análisis de costo-beneficio es que tal protocolo requiere mucho trabajo adicional para ser implementado por los buenos, y no hay evidencia de que las malas compras puedan romper la SHA-256.

    
respondido por el Atsby 14.07.2015 - 03:52
fuente
1

Si cambias de:

myhash = Hash1(Hash2(Hash3(password ^ salt)))

... a ...

myhash = Hash1(password + salt + Hash2(password + salt + Hash3(password ^ salt)))

... entonces es posible que haya reducido el riesgo de una colisión de Hash1 ...

    
respondido por el KristoferA 12.07.2015 - 17:35
fuente

Lea otras preguntas en las etiquetas