¿Qué función hash criptográfica debo elegir?

El .NET framework se envía con 6 algoritmos hash diferentes:

  • MD5: 16 bytes (Tiempo de hash 500MB: 1462 ms)
  • SHA1: 20 bytes (1644 ms)
  • SHA256: 32 bytes (5618 ms)
  • SHA384: 48 bytes (3839 ms)
  • SHA512: 64 bytes (3820 ms)
  • RIPEMD: 20 bytes (7066 ms)

Cada una de estas funciones funciona de manera diferente; MD5 es el más rápido y RIPEMD es el más lento.

MD5 tiene la ventaja de que encaja en el tipo de Guid incorporado. Lo que lo hace realmente fácil de usar para la identificación.

Sin embargo, MD5 es vulnerable a los ataques de colisión , SHA1 también es vulnerable pero en menor grado.

¿Bajo qué condiciones debo usar qué algoritmo hash?

Las preguntas particulares que realmente siento curiosidad por ver respondidas son:

  • ¿No se puede confiar en MD5? En situaciones normales, cuando utiliza el algoritmo MD5 sin intención maliciosa y ningún tercero tiene intención maliciosa, usted esperaría CUALQUIER colisión (es decir, dos bytes arbitrarios [] produciendo el mismo hash)

  • ¿Cuánto mejor es RIPEMD que SHA1? (si es mejor) es 5 veces más lento de calcular, pero el tamaño de hash es el mismo que SHA1.

  • ¿Cuáles son las probabilidades de obtener colisiones no maliciosas al mezclar nombres de archivo (u otras cadenas cortas)? (Por ejemplo, 2 nombres de archivo aleatorios con el mismo hash MD5) (con MD5 / SHA1 / SHA2xx) En general, ¿cuáles son las probabilidades de colisiones no maliciosas?

Este es el punto de referencia que utilicé:

static void TimeAction(string description, int iterations, Action func) { var watch = new Stopwatch(); watch.Start(); for (int i = 0; i < iterations; i++) { func(); } watch.Stop(); Console.Write(description); Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds); } static byte[] GetRandomBytes(int count) { var bytes = new byte[count]; (new Random()).NextBytes(bytes); return bytes; } static void Main(string[] args) { var md5 = new MD5CryptoServiceProvider(); var sha1 = new SHA1CryptoServiceProvider(); var sha256 = new SHA256CryptoServiceProvider(); var sha384 = new SHA384CryptoServiceProvider(); var sha512 = new SHA512CryptoServiceProvider(); var ripemd160 = new RIPEMD160Managed(); var source = GetRandomBytes(1000 * 1024); var algorithms = new Dictionary(); algorithms["md5"] = md5; algorithms["sha1"] = sha1; algorithms["sha256"] = sha256; algorithms["sha384"] = sha384; algorithms["sha512"] = sha512; algorithms["ripemd160"] = ripemd160; foreach (var pair in algorithms) { Console.WriteLine("Hash Length for {0} is {1}", pair.Key, pair.Value.ComputeHash(source).Length); } foreach (var pair in algorithms) { TimeAction(pair.Key + " calculation", 500, () => { pair.Value.ComputeHash(source); }); } Console.ReadKey(); } 

En criptografía, las funciones hash proporcionan tres funciones separadas.

  1. Resistencia a colisiones : ¿Cuán difícil es para alguien encontrar dos mensajes ( cualesquiera dos mensajes) que tengan el mismo efecto?
  2. Resistencia de preimagen : dado un hash, ¿qué tan difícil es encontrar otro mensaje que tenga el mismo hash? También conocido como una función de hash de una sola dirección .
  3. Segunda resistencia de preimagen : dado un mensaje, encuentre otro mensaje que tenga el mismo hash.

Estas propiedades están relacionadas pero son independientes. Por ejemplo, la resistencia a la colisión implica una segunda resistencia a la preimagen, pero no al revés. Para cualquier aplicación determinada, tendrá diferentes requisitos, necesitando una o más de estas propiedades. Una función hash para asegurar contraseñas en un servidor normalmente solo requerirá resistencia de preimagen, mientras que las resúmenes de mensajes requieren las tres.

Se ha demostrado que MD5 no es resistente a colisiones, sin embargo, eso no impide su uso en aplicaciones que no requieren resistencia a colisión. De hecho, MD5 a menudo todavía se usa en aplicaciones donde el tamaño de clave y la velocidad más pequeños son beneficiosos. Dicho esto, debido a sus defectos, los investigadores recomiendan el uso de otras funciones hash en nuevos escenarios.

SHA1 tiene un defecto que permite que las colisiones se encuentren teóricamente mucho menos que los 2 ^ 80 pasos que requeriría una función hash segura de su longitud. El ataque se está revisando continuamente y actualmente se puede hacer en ~ 2 ^ 63 pasos, apenas dentro del dominio actual de la computación. Por esta razón, el NIST está eliminando progresivamente el uso de SHA1, indicando que la familia SHA2 debería utilizarse después de 2010.

SHA2 es una nueva familia de funciones hash creadas después de SHA1. Actualmente no hay ataques conocidos contra las funciones de SHA2. SHA256, 384 y 512 son todos parte de la familia SHA2, solo usan diferentes longitudes de clave.

RIPEMD No puedo comentar mucho, excepto para señalar que no es tan comúnmente utilizado como las familias SHA, y por lo tanto no ha sido examinado tan de cerca por los investigadores criptográficos. Por esa sola razón, recomendaría el uso de funciones SHA sobre él. En la implementación que está usando parece bastante lento, lo que lo hace menos útil.

En conclusión, no hay una mejor función, todo depende de para qué la necesite. Tenga en cuenta los defectos con cada uno de ellos y podrá elegir la función de hash correcta para su escenario.

Todas las funciones hash están “rotas”

El principio del casillero dice que intente tan duro como lo desee, no puede caber más de 2 palomas en 2 hoyos (a menos que corte las palomas). De manera similar, no puede caber 2 ^ 128 + 1 números en 2 ^ 128 ranuras. Todas las funciones hash resultan en un hash de tamaño finito, esto significa que siempre puede encontrar una colisión si busca secuencias de “tamaño finito” + 1. Simplemente no es factible hacerlo. No para MD5 y no para Skein .

MD5 / SHA1 / Sha2xx no tienen colisiones fortuitas

Todas las funciones hash tienen colisiones, es un hecho de la vida. Cruzar estas colisiones por accidente equivale a ganar la lotería intergaláctica . Es decir, nadie gana la lotería intergaláctica , simplemente no es la forma en que funciona la lotería. No se encontrará con un hash accidental de MD5 / SHA1 / SHA2XXX, NUNCA. Cada palabra en cada diccionario, en cada idioma, tiene un valor diferente. Cada nombre de ruta, en cada máquina en todo el planeta tiene un hash MD5 / SHA1 / SHA2XXX diferente. ¿Cómo sé eso? Puedes preguntar. Bueno, como dije antes, nadie gana la lotería intergaláctica, nunca.

Pero … MD5 está roto

A veces, el hecho de que esté roto no importa .

Tal como está, no se conocen ataques previos o previos a la imagen previa en MD5.

Entonces, ¿qué hay de malo en MD5, puedes preguntar? Es posible que un tercero genere 2 mensajes, uno de los cuales es MALO y el otro es BUENO, ambos tienen el mismo valor. ( Ataque de colisión )

No obstante, la recomendación actual de RSA es no usar MD5 si necesita resistencia a la imagen previa. La gente tiende a errar por el lado de la precaución cuando se trata de algoritmos de seguridad.

Entonces, ¿qué función hash debo usar en .NET?

  • Use MD5 si necesita la velocidad / tamaño y no le importan los ataques de cumpleaños ni los ataques previos a la imagen.

Repita esto después de mí, no hay posibilidad de colisiones MD5 , las colisiones maliciosas pueden diseñarse cuidadosamente. Aunque hasta el momento no se conocen ataques previos a la imagen en MD5, la línea de los expertos en seguridad es que MD5 no se debe usar donde necesite defenderse contra los ataques previos a la imagen. MISMO va para SHA1 .

Tenga en cuenta que no todos los algoritmos necesitan defenderse contra ataques de pre-imagen o colisión. Tomemos el caso trivial de una búsqueda de primer paso para archivos duplicados en su HD.

  • Use la función basada en SHA2XX si quiere una función hash criptográficamente segura.

Nadie ha encontrado una colisión SHA512. NUNCA. Han intentado realmente duro. Para el caso, nadie ha encontrado nunca una colisión SHA256 o 384. .

  • No use SHA1 o RIPEMD a menos que sea para un escenario de interoperabilidad.

RIPMED no ha recibido la misma cantidad de escrutinio que SHAX y MD5 ha recibido. Tanto SHA1 como RIPEMD son vulnerables a los ataques de cumpleaños. Son más lentos que MD5 en .NET y vienen en el incómodo tamaño de 20 bytes. No tiene sentido utilizar estas funciones, olvídate de ellas.

Los ataques de colisión SHA1 han bajado a 2 ^ 52, no va a ser demasiado tiempo hasta que las colisiones SHA1 estén en libertad.

Para obtener información actualizada sobre las diversas funciones hash, eche un vistazo a la función hash zoo .

Pero espera, hay más

Tener una función hash rápida puede ser una maldición. Por ejemplo: un uso muy común para las funciones hash es el almacenamiento de contraseñas. Básicamente, calcula el hash de una contraseña combinada con una cadena aleatoria conocida (para impedir los ataques del arco iris) y almacena ese hash en la base de datos.

El problema es que si un atacante obtiene un volcado de la base de datos, puede adivinar con bastante efectividad las contraseñas usando fuerza bruta. Cada combinación que intenta solo lleva una fracción de milisegundo, y puede probar cientos de miles de contraseñas por segundo.

Para solucionar este problema, se puede utilizar el algoritmo bcrypt , que está diseñado para ser lento, por lo que el atacante se ralentizará mucho si ataca un sistema con bcrypt. Recientemente scrypt ha llegado a ser un titular y algunos lo consideran más efectivo que bcpt pero no conozco una implementación de .NET.

Actualizar:

Los tiempos han cambiado, tenemos un ganador de SHA3. Recomendaría usar el ganador de keccak (también conocido como SHA3 ) del concurso SHA3.

Respuesta Original:

En orden de más débil a más fuerte, diría:

  1. RIPEMD BROKEN, nunca debe ser utilizado como se puede ver en este pdf
  2. MD-5 BROKEN, nunca debe usarse, se puede romper en 2 minutos con una computadora portátil
  3. SHA-1 BROKEN, nunca debe usarse, está roto en principio, los ataques mejoran cada semana
  4. SHA-2 WEAK, probablemente se romperá en los próximos años. Se han encontrado algunas debilidades. Tenga en cuenta que, en general, cuanto mayor es el tamaño de la clave, más difícil es romperla. Si bien el tamaño de clave = fuerza no siempre es cierto, es mayormente cierto. Entonces SHA-256 es probablemente más débil que SHA-512.
  5. Skein SIN DEBILIDADES CONOCIDAS, es un candidato para SHA-3 . Es bastante nuevo y por lo tanto no probado. Se ha implementado en varios idiomas.
  6. MD6 SIN DEBILIDADES CONOCIDAS, es otro candidato para SHA-3. Probablemente más fuerte que Skien, pero más lento en máquinas de un solo núcleo. Al igual que Skien, no ha sido probado. Algunos desarrolladores con mentalidad de seguridad lo están usando, en roles de misión crítica .

Personalmente, usaría MD6, porque uno nunca podría haber sido demasiado paranoico. Si la velocidad es una preocupación real, miraría a Skein, o SHA-256.

Cuál de ellas realmente depende de para qué lo está usando. Si solo quiere asegurarse de que los archivos no se corrompan en tránsito y no le preocupe la seguridad, vaya rápido o pequeño. Si necesita firmas digitales para acuerdos de rescate federal de miles de millones de dólares y necesita asegurarse de que no se forjen, procure frenar y ralentizar.

Me gustaría comentar (antes de que md5 se rompa) que todavía uso md5 extensivamente a pesar de su quebrantamiento abrumador por una gran cantidad de criptografía.

Mientras no te importe proteger contra colisiones (aún puedes usar md5 en un hmac) y quieres la velocidad (a veces quieres un hash más lento), puedes usar md5 con confianza.

En defensa de MD5, no hay forma conocida de producir un archivo con un hash MD5 arbitrario. El autor original debe planear con anticipación una colisión laboral. Por lo tanto, si el receptor confía en el emisor, MD5 está bien. MD5 se rompe si el firmante es malicioso, pero no se sabe que sea vulnerable a los ataques de hombre en el medio.

Sería una buena idea echar un vistazo al algoritmo BLAKE2 .

Como se describe, es más rápido que MD5 y al menos tan seguro como SHA-3. También es implementado por varias aplicaciones de software , incluido WinRar.

No soy un experto en este tipo de cosas, pero me mantengo al día con la comunidad de seguridad y mucha gente considera que el hash md5 se ha roto. Diría que cuál usar depende de qué tan sensibles sean los datos y la aplicación específica. Es posible que pueda salirse con un hash ligeramente menos seguro siempre que la clave sea buena y fuerte.

Aquí están mis sugerencias para ti:

  1. Probablemente deberías olvidar MD5 si anticipas ataques. Hay muchas tablas rainbow para ellos en línea, y se ha sabido que corporaciones como la RIAA pueden producir secuencias con hashes equivalentes.
  2. Usa una sal si puedes. Incluir la longitud del mensaje en el mensaje puede hacer que sea muy difícil hacer una colisión hash útil.
  3. Como regla general, más bits significa menos colisiones (según el principio del casillero) y más lento, y tal vez más seguro (a menos que sea un genio matemático que puede encontrar vulnerabilidades).

Vea aquí un documento que detalla un algoritmo para crear colisiones md5 en 31 segundos con una computadora Intel P4 de escritorio.

http://eprint.iacr.org/2006/105