Ci sono tre caratteristiche principali che sono cercate in una funzione hash:
- Resistenza a preimmagini : dato x , sarà difficile trovare m tale che h (m) = x .
- Resistenza alle seconde preimmagini : date m e h (m) , sarà difficile trovare m (distinto da m ) tale che h (m) = h (m ') .
- Resistenza a collisioni : sarà difficile trovare m e m , distinti tra loro, tali che h (m) = h (m ') .
Per qualsiasi funzione di hash, indipendentemente dalla sua forza crittografica, esiste un attacco generico che funziona sempre e si chiama luck . Per trovare un preimage (o un secondo preimage), basta provare i messaggi casuali fino a quando non viene trovata una corrispondenza. Per trovare una collisione, hash molti messaggi casuali fino a quando due di questi producono lo stesso valore di hash. Per un output n -bit, la fortuna funziona con lo sforzo medio 2 n per le pre-immagini e le seconde pre-immagini, 2 n / 2 per le collisioni (quindi è sostanzialmente più facile trovare collisioni rispetto alle pre-immagini).
Ciò che è effettivamente necessario in una funzione hash dipende dal protocollo. Ad esempio, gli algoritmi firma digitale (quelli veri, come RSA o DSA) iniziano con una chiamata di funzione hash e l'hash il valore viene quindi utilizzato nell'algoritmo corretto. Le firme digitali funzionano sulla preimage e sulla seconda pre-resistenza, a meno che non ci si trovi in una configurazione in cui un potenziale attaccante può scegliere i dati di alcuni messaggi da firmare, nel qual caso è necessario anche resistere alle collisioni.
Come regola generale , attenersi all'output n -bit tale che 2 n / 2 invocazioni di la funzione di hash è troppo grande. Ciò significa n = 160 o così. Usando una funzione di hash con soli 128 bit di output significa che si possono trovare collisioni con lo sforzo 2 64 , che è piuttosto costoso ma tecnologicamente fattibile (un tale sforzo è stato eseguito almeno una volta ma ci sono voluti quattro anni e migliaia di contributori).
Per alcuni protocolli è sicuro ignorare le collisioni (che non otterrebbero nulla per l'attaccante) e quindi ridurre l'output a 80 bit (o giù di lì). E l'esempio è quando la funzione di hash viene usata come parte di HMAC per i controlli di integrità, ma solo fino a quando il la funzione di hash sottostante è solida . Infatti, HMAC si basa su alcune proprietà interne della funzione di hash che non sono direttamente collegate con la resistenza alle pre-immagini o alle collisioni. Se la funzione di hash è SHA-256, le cose vanno bene; HMAC / SHA-256 troncato a 96 bit (si tronca l'output di HMAC, non la funzione di hash interna) offrirà sicurezza fino a 2 96 , che è più che sufficiente . Se la funzione hash è MD5 o SHA-1, allora ... le cose sono meno chiare.
Ci vuole un crittografo esperto per dirti quale uso di una funzione di hash tollera il troncamento e quale no. Questo dipende dalla funzione hash stessa, da come viene usata e in quale contesto. Molti crittografi addestrati risponderanno "non farlo" nella maggior parte dei casi, comunque, perché gran parte della formazione sulla crittografia consiste nel rendersi conto che un singolo essere umano non sarà mai in grado di pensare a tutto. Sono un crittografo esperto e quindi ti dico: non farlo .