¿Cómo generar de manera simple y eficiente diferentes claves a partir de una contraseña?

3

Vi here que usar la misma clave para cifrar y mac (en ese orden) un mensaje podría eventualmente no ser seguro.

¿Cuál es la mejor manera de generar dos claves diferentes desde la misma contraseña (usando un PBKDF con una contraseña y un salt)?

  • ¿Generar una salida más larga y dividirla?
  • ¿Genera dos claves con la misma contraseña / sal pero con un número diferente de iteraciones?
  • ¿Genera dos claves usando la misma contraseña, pero diferentes sales?
  • ¿Algo más?

(Sé que usar un modo AEAD sería mejor, pero supongamos que no tengo otra opción)

    
pregunta SuperPython 13.02.2014 - 14:32
fuente

3 respuestas

5

Técnicamente, PBKDF2 puede producir una salida larga arbitraria (es una Key Derivation Function ), pero tiene problemas para eso: PBKDF2 usa HMAC sobre alguna función hash, que tiene una longitud de salida k bits (por ejemplo, k = 160 para el SHA-1 habitual). Si solicita más resultados que ese tamaño, entonces el costo computacional aumenta rápidamente: si desea 320 bits, costará el doble que 160 bits.

Desafortunadamente, aunque PBKDF2 está "fortalecido" para evitar los ataques de diccionario, el costo del atacante no aumentará tan rápido. Considere, por ejemplo, que utiliza PBKDF2 / SHA-1 para producir 256 bits de material clave: 128 bits para cifrado simétrico, y luego 128 bits para un MAC. Como defensor (el usuario normal) debes obtener tus 256 bits completos. El atacante, por otro lado, no necesita tanto; simplemente puede producir los primeros 128 bits, a la mitad del costo , y ver si el descifrado produce datos no basura.

Este es un problema conocido con PBKDF2. Tenga en cuenta que el mismo problema aparecería si utilizara otra función de hashing de contraseña dos veces, con dos sales diferentes: pagará el hashing dos veces, pero el atacante puede ignorar una de las claves y, por lo tanto, será dos veces más rápido que usted.

Si prefiere usar bcrypt, entonces se encuentra con otro problema, que es que bcrypt no es un KDF; Su tamaño de salida es de 192 bits. No más. Su tiempo de procesamiento no depende de su tamaño de salida, porque su tamaño de salida es fijo.

El método genérico es ejecutar una función de hash de contraseña y luego expandir la salida con un Key Derivation Function . Eso es lo que sugiere @CodesInChaos, con HKDF-Expand . Hay varios KDF por ahí; Normalmente, para mis propios diseños / propuestas, confío en HMAC_DRBG, de NIST SP800-90 y X9.62 (por ejemplo, en este ). Idealmente, desea un KDF que esté bien revisado, es decir, que haya sido investigado por criptógrafos, y no encontraron nada malo que decir al respecto (o, mejor aún, produjeron "pruebas de seguridad").

Si tiene prisa y no necesita mucho de material clave, un método relativamente más simple es codificar la salida de la función de hashing de contraseña con SHA-512. Esto le dará 512 bits de material clave.

    
respondido por el Tom Leek 13.02.2014 - 18:06
fuente
2

Al usar PBKDF2 puede especificar la longitud de salida de la clave de salida. Si desea generar dos claves de 256 bits, genere una salida de 512 bits y divídala. Se recomienda utilizar una sal larga, de modo que la entropía de ambas claves sea de 512 bits.

    
respondido por el DanielE 13.02.2014 - 14:53
fuente
1
  

¿Genera dos claves usando la misma contraseña, pero diferentes sales?   Esta es la respuesta correcta dada suficientemente larga y [criptográficamente] sales aleatorias. CodesInChaos hace dos buenos puntos: no exceda el tamaño de salida natural de su hash subyacente (160 bits para PBKDF2-HMAC-SHA-1, 512 bits para PBKDF2-HMAC-SHA-512, etc.) y una sal de 128 bits Probablemente esté bien, especialmente si está utilizando un cifrado de 128 bits.

Por RFC2898, una de las especificaciones PBKDF2 / RFC2898 / PKCS # 5 , sección 4.1: "Una sal En la criptografía basada en contraseña, tradicionalmente se ha utilizado el propósito de producir un gran conjunto de claves correspondientes a una contraseña determinada, entre las cuales una se selecciona al azar de acuerdo con la sal ". El resto de 4.1 entra en detalle sobre otras consideraciones para generar múltiples sales, en particular sobre cómo otras partes pueden decir fácilmente qué sal deben usar para qué operación. *

* I.e. Una respuesta (no mencionada explícitamente en el RFC) es generar sales tales que la sal que comienza con AA es para la primera operación, la sal que comienza con AB para la segunda, AC para la tercera, etc .; agregue un primer byte no aleatorio a la sal para un "indicador de ubicación", siempre que el resto de la sal sea criptográficamente aleatorio y lo suficientemente largo.

    
respondido por el Anti-weakpasswords 13.02.2014 - 15:16
fuente

Lea otras preguntas en las etiquetas