¿Hay algún problema serio con esta técnica para generar claves simétricas?

4

Estoy utilizando una técnica tomada de un libro de Bruce Schneier y Niels Ferguson llamado Criptografía práctica . Básicamente, se reduce a esto:

Bob hace esto:

pubk_A = clave pública de Alice

entropía = bytes de PRNG

encrypted_entropy = RSA_Encrypt pubk_A (entropía)

hashed_entropy = SHA2-512 (entropía)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

Bob luego envía encrypted_entropy a Alice.

Entonces Alice hace esto:

privk_A = clave privada de Alice

entropy = RSA_Decrypt privk_A (encrypted_entropy)

hashed_entropy = SHA2-512 (entropía)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

Esto funciona muy bien para generar claves que pueden usarse para comunicarse de Bob a Alice. Pero necesito llaves que pueda usar en ambas direcciones. Estaba pensando en modificar el algoritmo de esta manera:

Bob hace esto con entropía:

pubk_B = clave pública de Bob

hashed_entropy BA = SHA2-512 ( SHA2-256 (pubk_A) || entropy)

encrypt_key BA = hashed_entropy [0:32]
encrypt_nonce BA = hashed_entropy [32:48]
hmac_key BA = hashed_entropy [48:64]

hashed_entropy AB = SHA2-512 ( SHA2-256 (pubk_B) || entropy)

encrypt_key AB = hashed_entropy [0:32]
encrypt_nonce AB = hashed_entropy [32:48]
hmac_key AB = hashed_entropy [48:64]

Alice puede hacer lo mismo de su lado después de obtener la entropía al descifrar encrypted_entropy.

Como puede ver, ahora hay dos conjuntos de teclas, una utilizada para comunicarse de Bob a Alice y otra para comunicarse de Alice a Bob.

¿Hay algo malo con esto? ¿Qué riesgos de seguridad estoy tomando? ¿La seguridad del sistema es menor o mayor que si solo tuviera una parte modificada un poco en la lista? ¿Hay una mejor manera de manejar este problema sin agregar viajes de ida y vuelta?

    
pregunta Omnifarious 28.03.2011 - 19:56
fuente

3 respuestas

0

Con RSA puede transmitir con seguridad n-1 bytes de entropía según el tamaño de la clave elegida. Por lo tanto, una clave RSA de 2048 bits puede cifrar 2047 bits de datos, lo que es más que suficiente para un par de claves / nonce / hmac. El estiramiento de la entropía con una función de resumen del mensaje debe evitarse , sin embargo, hay más que suficiente entropía para circular siempre que el mensaje RSA no esté rellenado. El primer paso es dividir los 2047 bits de entropía a la mitad y hacer un hash de los resultados:

hashed_entropyA=SHA2-512(entropy[0:1023])
hashed_entropyB=SHA2-512(entropy[1024:2047])

El primer conjunto:

encrypt_keyB = hashed_entropyB[0:32]
encrypt_nonceB = hashed_entropyB[32:48]
hmac_keyB = hashed_entropyB[48:64]

El segundo conjunto:

encrypt_keyA = hashed_entropyA[0:32]
encrypt_nonceA = hashed_entropyA[32:48]
hmac_keyA = hashed_entropyA[48:64]

Los resultados son una forma independiente y sólida de derivación clave tal que dos partes pueden comunicarse. Un lado de la comunicación puede verse comprometido sin que todo el sistema se vea comprometido. Defensa en profundidad, seguridad en capas.

    
respondido por el rook 29.03.2011 - 16:47
fuente
5

Responde a tu pregunta específica: hay una forma más fácil de modificar su esquema para lograr lo que tienes en mente. Ir con lo que está en el libro, excepto hacer la siguiente modificación:

hashed_entropy = SHA2-512(0 || entropy) || SHA2-512(1 || entropy)

para que hashed_entropy ahora contenga 128 bytes. Ahora use los primeros 64 bytes para la dirección Bob- > Alicia (por ejemplo, extracción de claves y nonce como en el libro), y los siguientes 64 bytes para la dirección Alicia- > Bob (similarmente, extrayendo claves y nonce).

(Aquí escribo || para la concatenación de dos secuencias de bytes).

Nota importante de precaución: este esquema no autentica a Bob. No es adecuado para su uso en entornos donde se espera o se requiere autenticación mutua.

Comentario de alto nivel: traté de responder la pregunta específica que hiciste. Sin embargo, sería negligente si me detuviera allí. ¿Estás seguro de que estás haciendo la pregunta correcta? ¿Está seguro de que necesita implementar su propia forma de crear un canal seguro (cifrado y autenticado)?

Si bien Practical Cryptography es un libro fantástico, me resistiría a usar un diseño personalizado, incluso uno tomado de ese libro, a menos que no tuviera otra opción. Si fuera yo, primero haría un intento serio de reutilizar un diseño bien implementado y ampliamente implementado, por ejemplo, TLS. Solo si eso no cumple con mis requisitos, entonces consideraría hacer algo personalizado.

Mi crítica no tiene nada que ver con la calidad de Practical Cryptography , sino con la amplia variedad de cosas que pueden salir mal si diseñas e implementas tu propio canal seguro (incluido, por ejemplo, sutil fallas de implementación que pueden ser introducidas).

    
respondido por el D.W. 29.03.2011 - 08:30
fuente
1

Lo que desea es una Función de derivación de claves : un KDF toma como entrada una "clave maestra" (aquí, su "entropía") y produce tantos bytes como sea necesario para su criptografía simétrica. Una única llamada de función hash es un KDF en bruto que produce tanta salida como el tamaño de salida de la función hash, es decir, 64 bytes para SHA-512.

Muchos protocolos incluyen un KDF personalizado. Por ejemplo, en SSL / TLS , la función "PRF" (definida en la sección 5) es una construcción que utiliza la función hash subyacente (generalmente SHA-256 para TLS 1.2) en HMAC , repetidamente. Otro KDF estándar es PBKDF2 (sección 5.2). En realidad, cualquier buen cifrado de flujo sería un KDF decente (consulte el Proyecto eSTREAM para obtener información sobre buenos cifrados de flujo).

Otra opción sería ser menos desperdicio con su material clave. Desde los nombres que le da a los elementos derivados ("encrypt_key", "encrypt_nonce", "hmac_key"), supongo que desea cifrar cosas simétricamente, con una verificación de integridad con clave. El cifrado simétrico y el MAC juntos no son una tarea fácil; Hay muchas trampas ocultas. Lo inteligente es usar el modo encriptación autenticada para un cifrado de bloque. Un modo AE combina el cifrado simétrico y la verificación de integridad, y maneja internamente su propio KDF. Sugiero EAX . Dicho modo solo requiere un "nonce": es un IV con un solo requisito, es decir, no debe usarse dos veces con la misma clave. Esto produciría el siguiente protocolo:

  • Bob obtiene algunos bytes M de un PRNG (al menos 16 bytes).
  • Bob cifra M con la clave pública de Alice; Alice usará aquí la clave privada para obtener M .
  • Tanto Alice como Bob calculan SHA-256 ( M ) produciendo una cadena de 32 bytes K .
  • Luego, Bob envía mensajes a Alice, utilizando K [0..15] como clave con el modo EAX; el nonce es un contador de mensajes (1 para el primer mensaje, 2 para el segundo mensaje, etc.). El nonce puede adjuntarse a cada mensaje, o Alicia lo conoce implícitamente (por ejemplo, los "mensajes" son registros sucesivos en una conexión TCP).
  • Del mismo modo, Alice puede enviar mensajes a Bob, utilizando K [16..31] como clave con el modo EAX.

Y aquí está: solo se requieren 256 bits de material de clave inicial, por lo que una simple invocación de función hash estará bien; no se necesita KDF torpe.

Pero, en realidad, eso es solo reinventar SSL. Eso está bien para fines de investigación / educación, pero, para cualquier cosa que deba implementarse en la práctica, debe atenerse a los protocolos estándar donde los problemas de seguridad y los obstáculos de implementación ya han sido reconocidos (dolorosamente). ¿Mencioné SSL?

    
respondido por el Thomas Pornin 26.09.2011 - 21:33
fuente

Lea otras preguntas en las etiquetas