¿Qué hay de combinar pkdf2 con scrypt? [duplicar]

5

¿Cómo se ve el siguiente esquema de hash de contraseña?

iterations1 = scrypt iterations required to spend 50ms on my hardware
iterations2 = pbkdf2 iterations required to spend 50ms on my hardware
ram1 = scrypt suggested default ram requirement
salt1 = urandom
salt2 = urandom
hash = scrypt(pbkdf2(password, salt2+pepper, iterations2), iterations1, ram1, salt1+pepper)
save(username, hash, salt1, salt2, iterations1, iterations2, ram1)

Esta lectura fue impulsada por mi lectura de este artículo: enlace .

Esto es para permitirme aprovechar las excelentes funciones de scrypt, así como para aprovechar la seguridad probada de pbkdf2. ¿Es un enfoque razonable? ¿Crees que debería limitar esto para usar solo uno de los dos algoritmos, o crees que solo debería usar 1 sal compartida para ambos algoritmos?

    
pregunta George Bailey 03.10.2012 - 20:46
fuente

5 respuestas

3

Combinando diluye tu ventaja. Este negocio lento tiene que ver con luchar contra el atacante en igualdad de condiciones, su CPU contra su CPU; scrypt iguala aún más las cosas al optimizar el hashing de contraseña para el tipo de hardware que usa (una PC) en lugar de permitir que el atacante optimice las cosas de su lado con hardware que no sea PC. Si gasta la mitad de su presupuesto de CPU en PBKDF2, entonces esa la mitad se desperdicia un poco, ya que el atacante puede optimizar PBKDF2 a fondo con una GPU.

Consulte esta respuesta para obtener más información sobre el tema.

El artículo que cita parece ser de dudosa calidad. Por ejemplo, habla mal de bcrypt sobre la base de supuestas debilidades en 3DES, pero bcrypt no es en absoluto acerca de 3DES, y tampoco se conoce ningún ataque de costo académico de "80 bits" en 3DES. Le sugiero que no confíe demasiado en ese artículo.

    
respondido por el Thomas Pornin 03.10.2012 - 21:08
fuente
1

No veo ningún punto en el uso de scyrpt con pkdf2. scrypt le permite definir la cantidad de CPU y memoria necesaria para producir un hash en particular. Para hacer esto, scrypt se comporta de manera muy parecida a pbkdf2, en el sentido de que pasa por una función hash para producir esta salida.

pkdf2 + bcrypt es un excelente método de almacenamiento de contraseñas, pero creo que scrypt es mejor que esto porque también puedes aumentar el uso de memoria.

    
respondido por el rook 03.10.2012 - 20:58
fuente
1

Bueno, para empezar, le falta un argumento a pbkdf2, es decir, la longitud de la salida. Esto se controla literalmente truncando a n bloques de la función de entrada después de que haya pasado por el algoritmo pbkdf2

La razón por la que menciono esto es que la combinación de las dos funciones como esta podría ser potencialmente su perdición. Si, digamos hipotéticamente, decidió generar solo un byte de salida de pbkdf2. Genial, ahora tienes 2 ^ 8 entradas posibles para scrypt. Incluso con requisitos costosos, 256 entradas posibles no son difíciles de fuerza bruta. Luego, desde cualquier hash de contraseña dado, puede volver al estado post-pbkdf2.

El hecho de que solicitar un byte de salida de pbkdf2 trunca el hmac presenta una posibilidad interesante: ya no es necesario encontrar una colisión entre 2 ^ 160 (para pkcs # 5 con hmac-sha1) sino solo 2 ^ 8. En inglés, no necesita encontrar la contraseña , necesita encontrar una contraseña que funcione.

Por supuesto, este ejemplo en particular solo ocurre si decides generar una salida muy pequeña desde pbkdf2, pero es un ejemplo de cómo mientras los primitivos que usas están bien examinados, lo que estás haciendo con ellos puede ser malo. Para más información sobre el truncamiento de hash, lea ¿Truncar el hash criptográfico hace que sea imposible de romper? .

Personalmente iría con pbkdf2 o scrypt, y no con ambos.

    
respondido por el user2213 03.10.2012 - 21:03
fuente
1

Esto no proporciona tanto beneficio como podría pensar. Usted es igual de vulnerable a cualquier tipo de ataque en el hash interno, lo que reduce significativamente su seguridad, ya que permite la manipulación de los datos de una manera que hace que el hash interno sea anormal. Una mejor solución es xor las salidas de los dos hashes.

h1 = M_a(m, salt1, params_a)
h2 = M_b(m, salt2, params_b)
hash = h1 ^ h2
save(username, hash, salt1, salt2, params_a, params_b)

Esto garantiza que usted tenga la seguridad de al menos el hash más fuerte, sin los inconvenientes mencionados anteriormente. Tenga en cuenta que esto solo es cierto para los hashes con construcciones completamente diferentes, lo que resulta en una "prueba" de seguridad mal definida (o falta de ella).

De cualquier manera, probablemente no sea una buena idea combinar funciones, porque no hay garantía de que interactúen de la forma que esperas. Las funciones criptográficas son en su mayoría una casa de naipes y, como Thomas Pornin dijo con tanta elocuencia, una oración a $DEITY . Mezclarlos juntos hace que aparezcan incógnitas. Si bien es difícil decir que es defectuoso o más fuerte, en general se trata de esperar lo mejor.

Sin embargo , todo esto supone que su premisa es válida. Es mejor usar scrypt, que ofrece la misma fuerza que PBKDF2 y bcrypt combinados, con funciones adicionales diseñadas para hacer que la aceleración de GPU y FPGA sea muy ineficiente y difícil.

    
respondido por el Polynomial 03.10.2012 - 21:00
fuente
0

Con respecto a PBKDF2 vs bcrypt: bcrypt es más difícil de atacar a través de hardware dedicado, por lo que debería ser significativamente más fuerte. Es posible que bcrypt pueda tener problemas, pero se basa en una función bien conocida y parece que no Tengo algún problema en los 13 años que lleva existiendo.

PBKDF2 es un estándar con más control, pero también es mucho más fácil de atacar a través de un hardware dedicado, por lo que podría dejar claro que su seguridad es conocida para ser dañada de manera tal que bcrypt isn ' t (todavía).

En la misma línea, bcrypt es mucho más fácil de atacar a través de hardware dedicado que scrypt. La diferencia es que scrypt se presentó hace 3 años, contra 13 para bcrypt.

Además, scrypt es aparentemente considerado como un estándar IETF , así que espero que Tendré mucho más control pronto.

En cuanto a si debe encadenar dos funciones, estas preguntas responda mejor que yo (la segunda es sobre bcrypt + PBKDF2 pero no importa cuáles son las funciones en cuestión):

  

Así que no obtienes algo más fuerte de esa manera; en su lugar, obtiene un nivel de seguridad que es un promedio de lo que habría obtenido solo con Bcrypt, o solo con PBKDF2.

     

Combinar dos funciones hash o funciones similares es bueno para evitar un fallo catastrófico, si resulta que uno está roto; pero, suponiendo que tanto Bcrypt como PBKDF2 sean fuertes, y la pregunta es principalmente sobre el rendimiento (tanto bcrypt como PBKDF2 son sobre cómo hacer más lenta la búsqueda exhaustiva, por lo que todo se trata de rendimiento). Para una lentitud óptima, combinar bcrypt y PBKDF2 no es una buena idea.

Vale la pena señalar que el "fallo catastrófico" parece bastante improbable. Quiero decir, se sabe que MD5 está roto, pero PBKDF2 con MD5 sigue siendo "suficientemente bueno". Claro que es demasiado rápido, pero puedes subir las iteraciones. Claro que no es bueno para la resistencia a la colisión, pero es poco probable que sea un problema con contraseñas de longitud razonable (menos de cien caracteres).

    
respondido por el Brendan Long 03.10.2012 - 21:03
fuente

Lea otras preguntas en las etiquetas