¿Se pueden usar las salidas AES y SHA-256 con las mismas entradas para romperse entre sí?

3

Una representación abstracta de mi pregunta es así:

byte[] encrypted = AES.Encrypt(bytesToEncrypt, password);
byte[] hash = SHA256.Hash(password);

Si un atacante obtiene los valores de encrypted y hash , ¿eso les da una ventaja que no tendrían si solo tuvieran una o la otra?

    
pregunta user875234 09.06.2018 - 20:52
fuente

2 respuestas

3

Esto es seguro si la contraseña es segura. Por ejemplo, 16 bytes generados aleatoriamente como contraseña están bien, o tal vez una contraseña segura que se ejecutó a través de una buena función de derivación de claves (KDF) como bcrypt, scrypt o argon2 (cuanto más lenta mejor, entonces un atacante solo puede hacer conjeturas a un ritmo lento).

Le está dando más información al atacante, por lo que es casi inevitable que regale más información. Hay dos cosas en las que puedo pensar:

  • Romper uno, obtener el otro

    Su esquema se rompe si o bien alguien encuentra un ataque de preimagen en SHA2, o alguien encuentra algún ataque en AES que lleva a la recuperación de claves.

    Si un atacante solo tiene el hash y no el contenido cifrado, no puede usar un ataque en AES para romper su hash (y viceversa).

    Sin embargo, los ataques que rompen completamente AES o SHA2 son extremadamente improbables. Ambos algoritmos están muy bien estudiados y, por lo general, el craqueo se realiza al degradar sustancialmente un algoritmo. Si alguno de los dos está roto, estamos en un gran problema de todos modos.

  • Identificar una contraseña correcta adivinar

    Cuando se agrieta tu encrypted bytes, un atacante obtendrá basura aleatoria como resultado en cada intento incorrecto. Si su entrada ( bytesToEncrypt ) tampoco se puede distinguir de la aleatoria (por ejemplo, si es una ID de transacción de Bitcoin), un atacante nunca sabrá cuándo obtuvo la respuesta correcta. (Bueno, quizás podrían verificar todas las transacciones de Bitcoin en el historial y encontrar una que coincida ... pero entiendes la idea).

    Ahora, en cambio, pueden encontrar una entrada que corresponda al hash. Una vez que se encuentra, saben que la respuesta es correcta y pueden usarla para descifrar el mensaje.

    Por lo general, sin embargo, es posible verificar cuándo un descifrado es correcto, por lo que esta es solo una pequeña ventaja. Y esto supone que su contraseña se puede adivinar en primer lugar.

Como se dijo, ambos son muy improbables / inviables. Si su entrada password es segura, por ejemplo, 16 bytes aleatorios o una contraseña muy fuerte y KDF'd.

Entonces, su esquema es básicamente seguro, pero es solo una pequeña parte de una aplicación más grande. Si esta es una aplicación importante, debe hacer que un profesional la revise para asegurarse de que se haya implementado correctamente. (Nota: eso significa pagarle a alguien, no solo preguntar en un foro de revisión de códigos o algo así).

También, usted llama a sus entradas a la "contraseña" de AES y SHA2, lo que implica que está especificado por el usuario. Un KDF no está visible en el código que publicó, por lo que necesita para agregarlo. Use un KDF lento, como uno basado en bcrypt, scrypt o argon2.

    
respondido por el Luc 09.06.2018 - 23:06
fuente
2
  

dale al atacante una ventaja

Depende. ¿Qué intenta hacer el atacante?

Dado que usted llama a una de las piezas de datos involucradas "contraseña", asumo que el objetivo del atacante es encontrar esta contraseña, y su objetivo es mantenerla en secreto.

No está claro a qué te refieres con AES.Encrypt(bytesToEncrypt, password) . Supongo que quiere decir que está utilizando uno de los modos de operación de cifrado de bloque usando AES como el cifrado de bloque, siendo bytesToEncrypt la clave y password el mensaje a cifrar, o quizás al revés. A continuación, escribiré AES.Encrypt(key, message) , donde key es la clave de cifrado y message es la cadena para cifrar, ya que ese es el orden de los argumentos utilizados en prácticamente todas las API.

Si revela SHA256.Hash(password) , entonces el atacante puede encontrar la contraseña calculando SHA256.Hash(p) para muchos valores de p hasta que encuentren una con un hash matching coincidente. Pueden hacer los cálculos ellos mismos o aprovechar los cálculos realizados por otros. Esto podría ser devastador si el hash es algo así como b9f195c5cc7ef6afadbfbc42892ad47d3b24c6bc94bb510c4564a90a14e8b799 , a menos si se trata de algo así como Si revela AES.Encrypt(key, password) al atacante, entonces el atacante puede saber dos cosas:

  • Sabrán la longitud exacta o aproximada de la contraseña, según el modo de cifrado que usaste.
  • Si el atacante también logra obtener bytesToEncrypt , entonces sabrán la contraseña.

Si quisiera calcular AES.Encrypt(password, message) , entonces se encontraría con el problema de que esto realmente no tiene sentido. Una clave AES debe ser una cadena de 16 bytes, 24 bytes o 32 bytes. Ninguna otra longitud de cadena es posible: el algoritmo simplemente no está definido para otras longitudes de cadena. Si usa una contraseña que tiene la longitud de byte requerida, es una muy mala idea porque se supone que las claves se generan aleatoriamente. Si usa una contraseña que consta de caracteres imprimibles y tiene patrones que la hacen memorable, no está usando AES de la forma en que fue diseñada. Abre el camino a ataques de claves relacionadas : es posible aprender cosas de las relaciones entre claves, como "esto la clave consiste solo en caracteres ASCII "(es decir, el bit más significativo de cada byte es 0). AES tiene debilidades conocidas contra ataques de claves relacionadas, lo cual no es un problema en la práctica porque ningún protocolo sano involucra claves relacionadas. Sin embargo, usar una contraseña como clave no es un protocolo sano. Además, obviamente estás revelando algo acerca de la longitud de la contraseña y lo estás exponiendo al mismo tipo de ataque de fuerza bruta que el caso SHA-256 si se conoce message .

Encontrar la contraseña a través de su hash y encontrar la contraseña a través de su cifrado son bastante independientes. AES y SHA-256 son diseños no relacionados. Saber el cifrado revela el tamaño y, por lo tanto, facilita la búsqueda de una contraseña con un hash coincidente, pero solo de forma marginal. Saber que el hash no ayuda a romper el cifrado, a menos que encuentre la contraseña.

Revelar o bien el cifrado o el hash SHA-256 de una contraseña es una idea terrible, ya que cada una de ellas tiene debilidades evidentes (una se descompone si la clave se filtra, la otra es vulnerable a la bruta). ataques de fuerza). Las contraseñas solo deben almacenarse en forma de un hash lento y salado , y el hash debe mantenerse en secreto para una buena medida.

¹ En teoría, no sabrían si lo que encontraron es la contraseña real o alguna cadena diferente con el mismo hash. Sin embargo, no se conoce una forma de encontrar dos cadenas con el mismo hash SHA-256, y se necesitaría una búsqueda de fuerza bruta en todas las computadoras existentes en la actualidad aproximadamente la vida útil del universo para tener una posibilidad no despreciable de encontrar una. .

    
respondido por el Gilles 10.06.2018 - 01:00
fuente

Lea otras preguntas en las etiquetas