Domanda

Il framework .NET viene fornito con 6 diversi algoritmi di hashing:

  • MD5: 16 byte (tempo di hash 500 MB: 1462 ms)
  • SHA-1: 20 byte (1644 ms)
  • SHA256: 32 byte (5618 ms)
  • SHA384: 48 byte (3839 ms)
  • SHA512: 64 byte (3820 ms)
  • RIPEMD: 20 byte (7066 ms)

Ciascuna di queste funzioni svolge funzioni diverse; MD5 è il più veloce e RIPEMD il più lento.

MD5 ha il vantaggio di adattarsi al tipo Guid incorporato; ed è la base dell'UUID di tipo 3 . L'hash SHA-1 è la base dell'UUID di tipo 5. Il che li rende davvero facile da usare per l'identificazione.

MD5 tuttavia è vulnerabile a attacchi di collisione , SHA-1 è anche vulnerabile ma a un grado inferiore.

In quali condizioni dovrei usare quale algoritmo di hashing?

Domande particolari Sono davvero curioso di vedere le risposte sono:

  • MD5 non è affidabile? In situazioni normali quando si utilizza l'algoritmo MD5 senza intenzioni dannose e nessuna terza parte ha intenzioni dannose ci si aspetterebbe QUALSIASI collisione (ovvero due byte arbitrari [] che producono lo stesso hash)

  • Quanto è meglio RIPEMD di SHA1? (se è meglio) è 5 volte più lento da calcolare ma la dimensione dell'hash è la stessa di SHA1.

  • Quali sono le probabilità di ottenere collisioni non dannose quando si esegue l'hashing di nomi di file (o altre stringhe brevi)? (Ad esempio 2 nomi di file casuali con lo stesso hash MD5) (con MD5 / SHA1 / SHA2xx) In generale, quali sono le probabilità di collisioni non dannose?

Questo è il benchmark che ho usato:

    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<string,HashAlgorithm>();
        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();
    }
È stato utile?

Soluzione

Nella crittografia, le funzioni hash forniscono tre funzioni separate.

  1. Resistenza alle collisioni : quanto è difficile per qualcuno trovare due messaggi ( qualsiasi due messaggi) con lo stesso hash.
  2. Preimage Resistance : dato un hash, quanto è difficile trovare un altro messaggio che abbia lo stesso hash? Conosciuta anche come funzione hash unidirezionale .
  3. Seconda resistenza preimage : dato un messaggio, trova un altro messaggio con lo stesso hash.

Queste proprietà sono correlate ma indipendenti. Ad esempio, la resistenza alle collisioni implica una seconda resistenza preimmaginata, ma non viceversa. Per ogni data applicazione, avrai requisiti diversi, che richiedono una o più di queste proprietà. Una funzione hash per proteggere le password su un server di solito richiede solo la resistenza preimage, mentre i digest dei messaggi richiedono tutti e tre.

È stato dimostrato che MD5 non è resistente alle collisioni, tuttavia ciò non ne impedisce l'uso in applicazioni che non richiedono resistenza alle collisioni. In effetti, MD5 viene spesso utilizzato in applicazioni in cui le dimensioni e la velocità della chiave più piccole sono vantaggiose. Detto questo, a causa dei suoi difetti, i ricercatori raccomandano l'uso di altre funzioni di hash in nuovi scenari.

SHA1 ha un difetto che consente di trovare collisioni in teoria molto meno dei 2 ^ 80 passi richiesti da una funzione hash sicura della sua lunghezza. L'attacco viene continuamente rivisto e attualmente può essere eseguito in ~ 2 ^ 63 passaggi - appena all'interno dell'attuale regno della calcolabilità. Per questo motivo il NIST sta eliminando gradualmente l'uso di SHA1, affermando che la famiglia SHA2 dovrebbe essere utilizzata dopo il 2010.

SHA2 è una nuova famiglia di funzioni hash creata dopo SHA1. Attualmente non ci sono attacchi noti contro le funzioni SHA2. SHA256, 384 e 512 fanno tutti parte della famiglia SHA2, usando solo lunghezze di chiave diverse.

RIPEMD Non posso commentare troppo, se non per notare che non è così comunemente usato come le famiglie SHA, e quindi non è stato esaminato così attentamente dai ricercatori crittografici. Per questo motivo da solo consiglierei l'uso delle funzioni SHA su di esso. Nell'implementazione che stai usando, sembra anche piuttosto lento, il che lo rende meno utile.

In conclusione, non esiste una funzione migliore: tutto dipende da ciò di cui hai bisogno. Siate consapevoli dei difetti di ciascuno e sarete in grado di scegliere la funzione hash giusta per il il vostro scenario.

Altri suggerimenti

Tutte le funzioni hash sono & Quot; rotto & Quot;

Il principio del pigeonhole dice che sforzati quanto non puoi adattarti più di 2 piccioni in 2 buche (a meno che non si tagliano i piccioni). Allo stesso modo non è possibile inserire 2 ^ 128 + 1 numeri in 2 ^ 128 slot. Tutte le funzioni hash generano un hash di dimensioni finite, questo significa che puoi sempre trovare una collisione se cerchi tra & Quot; dimensioni finite & Quot; + 1 sequenze. Non è possibile farlo. Non per MD5 e non per Skein .

MD5 / SHA1 / Sha2xx non hanno collisioni casuali

Tutte le funzioni hash hanno delle collisioni, è un dato di fatto. Incontrare queste collisioni per caso è l'equivalente di vincere alla lotteria intergalattica . Vale a dire, nessuno vince la lotteria intergalattica , non è proprio il modo in cui funziona la lotteria. Non incontrerai mai un hash MD5 / SHA1 / SHA2XXX accidentale, MAI. Ogni parola in ogni dizionario, in ogni lingua, ha un valore diverso. Ogni nome di percorso, su ogni macchina nell'intero pianeta ha un diverso hash MD5 / SHA1 / SHA2XXX. Come faccio a saperlo, potresti chiedere. Bene, come ho detto prima, nessuno vince mai la lotteria intergalattica.

Ma ... MD5 è rotto

A volte il fatto che sia rotto non ha importanza .

Allo stato attuale non sono noti attacchi pre-immagine o seconda pre-immagine su MD5 .

Quindi, cosa c'è di così rotto in MD5, potresti chiedere? È possibile che una terza parte generi 2 messaggi, uno dei quali è MALE e un altro è BUONO che entrambi hanno lo stesso valore. ( Attacco di collisione )

Tuttavia, l'attuale raccomandazione RSA non è di utilizzare MD5 se è necessaria la resistenza pre-immagine. Le persone tendono a sbagliare per precauzione quando si tratta di algoritmi di sicurezza.

Quindi quale funzione hash dovrei usare in .NET?

  • Usa MD5 se hai bisogno di velocità / dimensioni e non ti importa degli attacchi di compleanno o degli attacchi pre-immagine.

Ripeti questo dopo di me, non ci sono possibilità di collisioni MD5 , le collisioni dannose possono essere attentamente progettate. Anche se finora non sono noti attacchi pre-immagine su MD5, la linea degli esperti di sicurezza è che MD5 non dovrebbe essere usato dove è necessario difendersi dagli attacchi pre-immagine. SAME vale per SHA1 .

Tieni presente che non tutti gli algoritmi devono difendersi da attacchi pre-immagine o di collisione. Prendi il banale caso di una ricerca di primo passaggio per file duplicati sul tuo HD.

  • Utilizzare la funzione basata su SHA2XX se si desidera una funzione hash crittograficamente sicura.

Nessuno ha mai trovato alcuna collisione SHA512. MAI. Ci hanno provato davvero tanto. Del resto nessuno ha mai trovato collisioni tra SHA256 e 384. .

  • Non utilizzare SHA1 o RIPEMD se non per uno scenario di interoperabilità.

RIPMED non ha ricevuto la stessa quantità di controllo ricevuto da SHAX e MD5. Sia SHA1 che RIPEMD sono vulnerabili agli attacchi di compleanno. Sono entrambi più lenti di MD5 su .NET e hanno dimensioni scomode di 20 byte. È inutile usare queste funzioni, dimenticarsene.

Gli attacchi di collisione SHA1 sono scesi a 2 ^ 52, non sarà troppo lungo fino a quando le collisioni di SHA1 non saranno in circolazione.

Per informazioni aggiornate sulle varie funzioni hash dare un'occhiata a lo zoo della funzione hash .

Ma aspetta, c'è di più

Avere un digiuno può essere una maledizione. Ad esempio: un utilizzo molto comune per le funzioni hash è la memorizzazione delle password. In sostanza, si calcola l'hash di una password combinata con una stringa casuale nota (per impedire gli attacchi dell'arcobaleno) e si memorizza tale hash nel database.

Il problema è che se un utente malintenzionato ottiene un dump del database, può indovinare in modo abbastanza efficace le password usando la forza bruta. Ogni combinazione che prova richiede solo una frazione di millisecondo e può provare centinaia di migliaia di password al secondo.

Per aggirare questo problema, è possibile utilizzare l'algoritmo bcrypt , progettato per essere lento, quindi l'attaccante sarà fortemente rallentato se attacca un sistema usando bcrypt. Recentemente scrypt ha fatto alcuni titoli ed è considerato da alcuni per essere più efficace di bcrypt ma non conosco un'implementazione .Net.

Aggiornamento:

I tempi sono cambiati, abbiamo un vincitore SHA3. Consiglierei di utilizzare keccak (aka SHA3 ) vincitore del concorso SHA3.

Risposta originale:

In ordine di più debole a più forte direi:

  1. RIPEMD BROKEN, non dovrebbe mai essere usato come si può vedere in questo pdf
  2. MD-5 BROKEN, non dovrebbe mai essere usato, può essere rotto in 2 minuti con un laptop
  3. SHA-1 BROKEN, non dovrebbe mai essere usato, è rotto in linea di principio, gli attacchi stanno migliorando di settimana in settimana
  4. SHA-2 WEAK, probabilmente verrà rotto nei prossimi anni. Sono stati riscontrati alcuni punti deboli. Si noti che generalmente la dimensione della chiave più alta, più difficile la funzione hash è quella di rompersi. Mentre la dimensione chiave = forza non è sempre vera, è per lo più vera. Quindi SHA-256 è probabilmente più debole di SHA-512.
  5. Matassa NESSUNA DEBOLEZZA CONOSCIUTA, è un candidato per SHA-3 . È abbastanza nuovo e quindi non testato. È stato implementato in diverse lingue.
  6. MD6 NESSUNA DEBOLEZZA CONOSCIUTA, è un altro candidato per SHA-3. Probabilmente più forte di Skien, ma più lento su macchine single core. Come Skien non è stato testato. Alcuni sviluppatori attenti alla sicurezza lo stanno utilizzando in ruoli mission critical .

Personalmente userei MD6, perché non si può mai essere troppo paranoici. Se la velocità è una vera preoccupazione guarderei Skein, o SHA-256.

A difesa di MD5, non esiste un modo noto per produrre un file con un hash MD5 arbitrario. L'autore originale deve pianificare in anticipo per avere una collisione funzionante. Pertanto, se il destinatario si fida del mittente, MD5 va bene. MD5 viene interrotto se il firmatario è dannoso, ma non è noto per essere vulnerabile agli attacchi man-in-the-middle.

Quello che usi davvero dipende da cosa lo stai usando. Se vuoi solo assicurarti che i file non vengano danneggiati durante il trasporto e che non siano così preoccupati per la sicurezza, vai veloce e piccolo. Se hai bisogno di firme digitali per accordi di salvataggio federali da svariati miliardi di dollari e devi assicurarti che non siano falsi, cerca di falsificare e rallentare.

Vorrei rinviare (prima che md5 venga distrutto) che uso ancora md5 ampiamente nonostante la sua schiacciante rottura per un sacco di criptovalute.

Finché non ti interessa proteggere dalle collisioni (sei comunque sicuro di usare md5 in un hmac) e vuoi la velocità (a volte vuoi un hash più lento) allora puoi comunque usare md5 con sicurezza .

Sarebbe una buona idea dare un'occhiata al BLAKE2 algorythm.

Come è descritto, è più veloce di MD5 e almeno sicuro come SHA-3. È inoltre implementato da diverse applicazioni software , incluso WinRar.

Non sono un esperto in questo genere di cose, ma resto al passo con la comunità della sicurezza e molte persone lì considerano l'hash md5 rotto. Direi che quale usare dipende dalla sensibilità dei dati e dall'applicazione specifica. Potresti riuscire a cavartela con un hash leggermente meno sicuro purché la chiave sia buona e potente.

Ecco i miei suggerimenti per te:

  1. Probabilmente dovresti dimenticare MD5 se prevedi gli attacchi. Ci sono molti tavoli arcobaleno per loro online e aziende come la RIAA sono state conosciute per essere in grado per produrre sequenze con hash equivalenti.
  2. Usa un salt se puoi. Includere la lunghezza del messaggio nel messaggio può rendere molto difficile fare una collisione hash utile.
  3. Come regola generale, più bit significa meno collisioni (secondo il principio del buco di piccione) e più lento e forse più sicuro (a meno che tu non sia un genio della matematica che può trovare vulnerabilità).

Vedi qui per un documento che descrive in dettaglio un algoritmo per creare collisioni md5 in 31 secondi con un computer desktop Intel P4.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top