¿SHA-1 es seguro para el almacenamiento de contraseñas?

Conclusión: SHA-1 es tan seguro como cualquier cosa contra los ataques de preimagen, sin embargo es fácil de computar, lo que significa que es más fácil montar un ataque de fuerza bruta o de diccionario. (Lo mismo es cierto para sucesores como SHA-256.) Dependiendo de las circunstancias, una función hash que fue diseñada para ser computacionalmente costosa (como bcrypt) podría ser una mejor opción.


Algunas personas comentan que “SHA-1 está roto” mucho, así que estoy tratando de entender qué significa exactamente eso. Supongamos que tengo una base de datos de hashes de contraseñas SHA-1, y un atacante con un avanzado algoritmo de última hora SHA-1 y una botnet con 100.000 máquinas acceden a él. (Tener control sobre 100k computadoras domésticas significaría que pueden hacer aproximadamente 10 ^ 15 operaciones por segundo.) ¿Cuánto tiempo necesitarían para

  1. averiguar la contraseña de cualquier usuario?
  2. averiguar la contraseña de un usuario determinado?
  3. averiguar la contraseña de todos los usuarios?
  4. encontrar una forma de iniciar sesión como uno de los usuarios?
  5. encontrar una manera de iniciar sesión como un usuario específico?

¿Cómo cambia eso si las contraseñas son saladas? ¿El método de salazón (prefijo, postfix, ambos, o algo más complicado como xor-ing) importa?

Aquí está mi comprensión actual, después de buscar en Google. Por favor corrija en las respuestas si entendí mal algo.

  • Si no hay sal, un ataque de arco iris encontrará inmediatamente todas las contraseñas (excepto las extremadamente largas).
  • Si hay una sal aleatoria suficientemente larga, la forma más efectiva de descubrir las contraseñas es una fuerza bruta o un ataque de diccionario. Ni la colisión ni los ataques de preimagen ayudan a descubrir la contraseña real, por lo que los ataques criptográficos contra SHA-1 no son de ayuda aquí. Ni siquiera importa mucho qué algoritmo se use, incluso se podría usar MD5 o MD4 y las contraseñas serían igual de seguras (hay una pequeña diferencia porque el cálculo de un hash SHA-1 es más lento).
  • Para evaluar cuán seguro es “igual de seguro”, supongamos que una única ejecución sha1 toma 1000 operaciones y las contraseñas contienen mayúsculas, minúsculas y dígitos (es decir, 60 caracteres). Eso significa que el atacante puede probar 10 15 * 60 * 60 * 24/1000 ~ = 10 17 contraseña potencial al día. Para un ataque de fuerza bruta, eso significaría probar todas las contraseñas de hasta 9 caracteres en 3 horas, hasta 10 caracteres en una semana, hasta 11 caracteres en un año. (Se necesitan 60 veces más para cada personaje adicional). Un ataque de diccionario es mucho, mucho más rápido (incluso un atacante con una sola computadora podría lograrlo en horas), pero solo encuentra contraseñas débiles.
  • Para iniciar sesión como usuario, el atacante no necesita encontrar la contraseña exacta; es suficiente para encontrar una cadena que resulte en el mismo hash. Esto se llama un primer ataque de preimagen. Por lo que pude encontrar, no hay ataques de preimagen contra SHA-1. (Un ataque de fuerza bruta tomaría 2 160 operaciones, lo que significa que nuestro atacante teórico necesitaría 10 30 años para llevarlo a cabo. Los límites de la posibilidad teórica son alrededor de 2 60 operaciones, en las cuales el ataque tomaría algunos años). Hay ataques de preimagen contra versiones reducidas de SHA-1 con efecto insignificante (para el SHA-1 reducido que usa 44 pasos en lugar de 80, el tiempo de ataque se reduce de 2 160 operaciones a 2 157 ). Hay ataques de colisión contra SHA-1 que están dentro de la posibilidad teórica ( lo mejor que encuentro baja el tiempo de 2 80 a 2 52 ), pero esos son inútiles contra hash de contraseñas, incluso sin salazón.

En resumen, almacenar contraseñas con SHA-1 parece perfectamente seguro. ¿Me he perdido algo?

Actualización: Marcelo señaló un artículo que menciona un segundo ataque de preimagen en 2 106 operaciones . ( Editar: Como explica Thomas , este ataque es una construcción hipotética que no se aplica a escenarios de la vida real.) Sin embargo, aún no veo cómo esto deletrea peligro para el uso de SHA-1 como una función de derivación clave. ¿Hay generalmente buenas razones para pensar que un ataque de colisión o un segundo ataque de preimagen pueden eventualmente convertirse en un primer ataque de preimagen?

La respuesta breve a su pregunta es: SHA-1 es lo más seguro que puede obtener. MD5 estaría bien también, incluso MD4; pero podría poner nerviosos a algunos inversores. Para las relaciones públicas , lo mejor es utilizar una función hash “mejor”, por ejemplo, SHA-256, incluso si trunca su salida a 160 o 128 bits (para ahorrar en el costo de almacenamiento). Algunos de los candidatos a la ronda 2 de SHA-3 parecen ser más rápidos que SHA-1 mientras que podrían decirse que son “más seguros”; sin embargo, todavía son un poco nuevos, por lo que apegarse a SHA-256 o SHA-512 sería una ruta más segura en este momento. Te haría lucir profesional y prudente, lo cual es bueno.

Tenga en cuenta que “tan seguro como pueda” no es lo mismo que “perfectamente seguro”. Vea a continuación explicaciones bastante largas.

Acerca de los ataques conocidos:

Los ataques conocidos en MD4, MD5 y SHA-1 son sobre colisiones, que no afectan la resistencia a la preimagen. Se ha demostrado que MD4 tiene algunas debilidades que pueden (solo teóricamente) explotarse al intentar romper HMAC / MD4, pero esto no se aplica a su problema. El ataque de 2 106 segundos de preimagen en el documento de Kesley y Schneier es una compensación genérica que se aplica solo a entradas muy largas (2 60 bytes, es decir un millón de terabytes), observe cómo 106 + 60 excede de 160; ahí es donde se ve que el intercambio no tiene nada de mágico).

El rest de este mensaje asume que la función hash que usas (por ejemplo, SHA-1) es una “caja negra” sin ninguna propiedad especial que el atacante pueda usar. Eso es lo que tienes ahora incluso con las funciones hash “rotas” MD5 y SHA-1.

Acerca de las tablas de arco iris:

El “ataque del arco iris” es en realidad el costo compartido de un diccionario o un ataque de fuerza bruta. Es un derivado del intercambio de tiempo-memoria descrito por primera vez por Hellman en 1980. Suponiendo que tiene N contraseñas posibles (ese es el tamaño de su diccionario, o 2 n si considera la fuerza bruta una función hash con una salida de n bits), hay un ataque de tiempo compartido en el que se precalculan las contraseñas N hashed y se almacenan en una tabla grande. Si ordena las salidas de hash, puede obtener su contraseña en una sola búsqueda. Una mesa de arcoiris es una forma inteligente de almacenar esa mesa con un espacio muy reducido. Almacena solo contraseñas hash N / t y descifra contraseñas con búsquedas O ( t 2 ). Las tablas Rainbow le permiten manejar virtualmente tablas precalculadas mucho más grandes que las que puede almacenar de manera realista.

Sin embargo, el arco iris o no, el atacante todavía tiene que ejecutar el ataque completo al menos una vez. Esto se puede ver como varias capas de optimización sucesivas:

  1. El ataque de fuerza bruta / diccionario le ha costado a N descifrar cada contraseña.
  2. Con una tabla pre calculada, el atacante paga el costo N una vez y luego puede atacar muchas contraseñas con un costo adicional muy pequeño por cada contraseña.
  3. Si la tabla pre calculada es una tabla arcoiris, entonces N puede ser algo más grande, porque el costo de almacenamiento se reduce. El cuello de botella en N se convierte en la potencia de CPU que el atacante puede reunir, no en el tamaño de sus discos duros.

Si N es lo suficientemente grande como para que el costo de la CPU de hash N contraseñas sea ridículo, entonces tal ataque no es factible, independientemente de si las tablas del arco iris se usan o no. Esto significa que una función hash (resistente a las imágenes) con una salida de 80 bits o más es suficiente para que el ataque de fuerza bruta no sea factible.

Acerca de sales:

Las sales son una forma de vencer los pre-cálculos. En la descripción anterior, la sal devuelve al atacante al paso 1: la salazón evita que el atacante comparta el costo O ( N ) entre varias contraseñas atacadas. Las tablas pre calculadas, a fortiori las tablas del arco iris, ya no son factibles.

Usted quiere salazón porque cuando los datos hash consisten en contraseñas , es decir, algo que se ajusta dentro del cerebro de un ser humano al azar, entonces N puede ser bastante bajo: los humanos son realmente malos al elegir y recordar contraseñas. De esto se tratan los “ataques de diccionario”: es decir, se usa un espacio reducido de contraseñas potenciales (el “diccionario”) bajo la suposición de que muchas contraseñas de usuario estarán en ese espacio especialmente seleccionado.

Por lo tanto, la salazón evitará al menos que el atacante use tablas precalculadas, en particular tablas de arco iris precalculadas. Esto supone que el atacante podrá romper una contraseña o dos; no queremos que rompa 1000 contraseñas adicionales con una pequeña carga adicional.

Además, la salazón es buena para las relaciones públicas.

Sobre el costo de SHA-1:

El costo elemental de SHA-1 es sobre hash un bloque de 64 bytes. Así es como funciona SHA-1: los datos se rellenan y luego se dividen en bloques de 64 bytes. El costo de procesar un solo bloque es de aproximadamente 500 ciclos de reloj en un sistema Intel Core2, y eso es para un solo núcleo. MD5 y MD4 son más rápidos, cuentan aproximadamente 400 y 250 ciclos, respectivamente. No olvide que la CPU más moderna tiene varios núcleos, así que multiplique en consecuencia.

Algunos esquemas de salazón prescriben enormes sales; por ejemplo, lo que entra en la función hash es en realidad 40000 copias sucesivas de una sola sal de 128 bits, seguida de la contraseña misma. Esto hace que el hashing de contraseñas sea más caro (por un factor de 10000 con mi ejemplo), tanto para el usuario legítimo como para el atacante. Si esta es una buena idea depende de la configuración. Para iniciar sesión en un sistema de escritorio, esto es bueno: el usuario ni siquiera notará que le llevó 10 ms codificar su contraseña, en lugar de 1 μs; pero el costo para el atacante ha aumentado en un factor muy notable 10000. En los servidores compartidos con miles de clientes por segundo, el costo total puede ser prohibitivo. Conceptualmente, subir el listón por el mismo factor para el usuario legítimo y el atacante no es en última instancia una buena seguridad; pero puede ser una idea valiosa en algunas situaciones específicas.

Acerca de los ataques en línea:

Todo lo anterior se trata de derrotar a los ataques fuera de línea . Un ataque fuera de línea es un ataque en el que el atacante tiene todos los datos que necesita para “probar” las contraseñas; por ejemplo, el atacante podría obtener una copia de la base de datos que contiene las contraseñas hash. En un ataque fuera de línea, el atacante está limitado solo por sus recursos computacionales. Por el contrario, un ataque en línea es un ataque donde cada conjetura del atacante debe pasar por un verificador honesto (por ejemplo, el atacante simplemente intenta iniciar sesión en el sistema atacado). Los ataques en línea se ven frustrados al imponer límites a la cantidad de contraseñas que se pueden probar por segundo. Ejemplos extremos son tarjetas inteligentes que se apagan después de tres PIN incorrectos.

Por lo general, para la seguridad de contraseñas, vale la pena mucho más organizar el sistema para que no permita que un atacante genere un ataque sin conexión. Eso es lo que hacen los sistemas Unix: las contraseñas hash, que solían estar en el /etc/password legible a nivel mundial, ahora están en el /etc/shadow que está protegido contra el acceso de lectura, excepto por unas pocas aplicaciones privilegiadas. La suposición aquí es que si el atacante puede leer /etc/shadow , entonces probablemente tenga suficiente control sobre el sistema que ya no necesita contraseñas …

Las respuestas anteriores no hacen ninguna mención de las GPU, que pueden hacer paralelo al hash SHA-1 en la medida en que una base de datos completa puede ser forzada en minutos u horas en lugar de días o semanas, incluso si las contraseñas han sido saladas.

Los algoritmos modernos hash de contraseñas como bcrypt o scrypt están diseñados específicamente para ser difíciles de ejecutar en GPU debido a que son cifras de bloque con requisitos de memoria mucho más altos (y el acceso a la memoria en una GPU no se puede paralelizar en la misma medida). También tienen una “función de trabajo” que les permite ser más lentos sobre la marcha a medida que la tecnología mejora.

En resumen, solo debe usar las mejores herramientas para el trabajo. Y SHA-1 queda muy lejos del estado de la técnica.

Para lectura adicional:

Su descripción suena precisa para el estado actual de la técnica.

Sin embargo, no deberías utilizar una sola iteración de ninguna función hash: al menos, deberías repetir muchas veces (1000 iteraciones del hash aumentan el trabajo del atacante 1000 veces. Aumenta tu trabajo en la misma cantidad, pero estás haciendo menos hashing de contraseñas de lo que son).

Idealmente, sin embargo, debería usar una primitiva de almacenamiento de contraseñas existente, como las que se describen aquí .

SHA1 es un resumen de mensaje , nunca fue una función de hash de contraseña (o de derivación de clave). (Aunque podría usarse como un bloque de construcción para un KDF, como en PBKDF2 con HMAC-SHA1).

Una función de hash de contraseñas debe defenderse contra ataques de diccionario y tablas de arcoiris. Varios algoritmos han sido diseñados para lograr este objective.

Actualmente, la mejor opción es probablemente Argon2 . Esta familia de funciones de hashing de contraseñas ganó la competencia Password Hashing en 2015.

Si Argon2 no está disponible, la única otra función estandarizada de encoding de contraseñas o derivación de claves es PBKDF2 , que es un estándar NIST antiguo. Otras opciones, si no se requiere el uso de un estándar, incluyen bcrypt y scrypt .

Wikipedia tiene páginas para estas funciones:

Se han descubierto vulnerabilidades graves en SHA-1 que hacen que la búsqueda sea mucho más rápida que la fuerza bruta. Todavía es en gran medida intratable, pero no se espera que sea así durante mucho más tiempo; los progtwigdores paranoicos prefieren algo de la familia SHA-2.

De este artículo con respecto al resultado original de 2005:

“Es hora de caminar, pero no correr, hacia las salidas de emergencia. No ves humo, pero las alarmas de incendio se han apagado”.

No es que el criptoanálisis actual haga al SHA-1 inseguro, sino que la comunidad crypto está preocupada de que peores noticias estén a la vuelta de la esquina. Este miedo también se aplica a SHA-2, que exhibe los mismos defectos que SHA-1, aunque en un espacio de búsqueda mucho más grande, de ahí la búsqueda constante de SHA-3 .

En resumen, SHA-1 es seguro en este momento, y probablemente lo haga por algún tiempo, pero la comunidad crypto no se siente cómoda con el pronóstico.

A partir de febrero de 2017, SHA-1 ya no debería considerarse seguro. Google ha reportado éxito con los ataques de colisión contra el SHA-1 completo y de scope no reducido ( enlace para informar ). Para el anuncio de Google, haga clic aquí .

Editar: Como señalaron otros, las contraseñas no son vulnerables a los ataques de colisión hash. Sin embargo, como guía general, no elegiría SHA-1 para aplicaciones relacionadas con la seguridad. Hay mejores alternativas por ahí.

Si almacena la contraseña salada, SHA-1 está bien para fines prácticos. SHA-2 se considera más seguro, pero SHA-1 no es un problema a menos que tenga una razón para ser verdaderamente paranoico.

Esto es lo que dice el NIST:

Los resultados presentados hasta el momento en SHA-1 no cuestionan su seguridad. Sin embargo, debido a los avances en la tecnología, el NIST planea retirarse de SHA-1 a favor de las funciones de hash más grandes y más fuertes (SHA-224, SHA-256, SHA-384 y SHA-512) para 2010.