MD5, SHA-1, SHA-256: quale hash, e per che cosa
Pubblicato il 01/07/2026 · 15 min di lettura · Strumenti per sviluppatori
Daniel Okonkwo — Sviluppatore front-end e redattore Tech presso OneKitly
Performance web · Formati di file
Verificato su 6 fonti
A una funzione di hash si chiedono tre garanzie distinte, e cadono in momenti diversi. Resistenza alla preimmagine: dato un digest, non puoi trovare alcun input che lo produca. Resistenza alla seconda preimmagine: dato un input, non puoi trovarne un altro con lo stesso digest. Resistenza alle collisioni: non puoi trovare due input qualsiasi che collidano. MD5 ha perso la resistenza alle collisioni nel 2004 (Wang et al.) e SHA-1 l'ha persa nel 2017, quando Google e il CWI di Amsterdam hanno pubblicato due PDF diversi con lo stesso digest SHA-1 dopo 9 223 372 036 854 775 808 valutazioni — esattamente 2^63. Nessuno dei due ha perso la resistenza alla preimmagine. Ecco perché «MD5 è rotto» è vero e viene applicato male di continuo. Confrontare un file scaricato con una somma MD5 per cogliere un trasferimento troncato funziona ancora, perché una corruzione accidentale non è un avversario che sceglie entrambi i file. Accettare un certificato firmato in MD5 no, perché lì l'avversario li sceglie entrambi. Usa SHA-256 per tutto ciò che è nuovo: md5("hello") vale 5d41402abc4b2a76b9719d911017c592, mentre sha256("hello") vale 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824. E nessuno di questi è un hash per password. Sono costruiti per essere veloci — misurati qui fra 632 MB/s e 1 357 MB/s su un solo core — mentre conservare password richiede lentezza. Quel lavoro spetta a bcrypt, scrypt o Argon2.
MD5 è rotto e MD5 va benissimo, a seconda di quale delle tre proprietà di sicurezza ti serviva. Ecco che cosa significano davvero resistenza alle collisioni, alla seconda preimmagine e alla preimmagine, quale algoritmo conserva quale, e perché nessuno di essi deve avvicinarsi a una password.
Tre proprietà, non una
Quasi ogni discussione sulle funzioni di hash deraglia già nella prima frase, perché la parola «sicuro» sta al posto di tre garanzie diverse. La resistenza alla preimmagine dice che, avendo solo un digest, non puoi risalire ad alcun input che lo produca. La resistenza alla seconda preimmagine dice che, dato un input specifico — questo contratto, questo binario —, non puoi trovarne un altro con lo stesso digest. La resistenza alle collisioni dice qualcosa di più forte e più strano: non puoi trovare alcuna coppia di input in collisione, nemmeno scegliendoli entrambi, nemmeno se nessuno dei due significa qualcosa.
Le tre si ordinano per difficoltà dell'attaccante, e il paradosso del compleanno spiega perché. Trovare una preimmagine per un digest di n bit costa circa 2^n operazioni; trovare una collisione ne costa solo circa 2^(n/2), perché non stai mirando a un bersaglio: aspetti che due dei tuoi candidati coincidano. Per SHA-256 sono 2^256 contro 2^128 — entrambi fuori portata. Per MD5 sono 2^128 contro 2^64 generici, e la crittanalisi ha spinto il numero reale molto più in basso. La resistenza alle collisioni è quindi sempre la prima a cadere, e cade moltissimo prima della resistenza alla preimmagine.
Che cosa si è davvero «rotto»
MD5 è caduto per primo. Xiaoyun Wang e coautori pubblicarono collisioni pratiche nel 2004 e in pochi anni la tecnica fu raffinata in collisioni a prefisso scelto, dove l'attaccante controlla l'inizio di entrambi i messaggi in collisione e può quindi rendere ciascuno un documento sensato. È questo che rende possibile falsificare una firma: fai firmare a una parte fidata la metà innocua di una coppia in collisione, poi attacchi la sua firma all'altra metà. Oggi una collisione MD5 semplice richiede secondi su hardware ordinario.
SHA-1 ha resistito fino a febbraio 2017, quando il CWI di Amsterdam e Google Research hanno pubblicato SHAttered: due file PDF visibilmente diversi con digest SHA-1 identico. Il loro annuncio quantifica il costo in 9 223 372 036 854 775 808 calcoli SHA-1. Quel numero non è arbitrario: è esattamente 2^63, comodamente sotto i 2^80 che un attacco del compleanno generico su un digest da 160 bit richiederebbe. Tre anni dopo, Leurent e Peyrin hanno esteso il risultato alle collisioni a prefisso scelto, e a quel punto SHA-1 era finito per ogni uso avversariale; le autorità di certificazione e i sistemi di controllo di versione che ancora lo emettevano hanno iniziato la lunga migrazione.
Nota che cosa nessuno dei due risultati dà all'attaccante. Nessuno può prendere un digest MD5 che pubblichi e recuperarne l'input. Nessuno può prendere un file esistente e fabbricare un secondo file con lo stesso MD5. Entrambi gli attacchi richiedono che l'avversario costruisca entrambe le metà fin dall'inizio. È esattamente il confine fra una checksum che coglie un download corrotto — la corruzione non ha scelto nulla — e una firma che deve sopravvivere a qualcuno che costruisce deliberatamente entrambi i documenti.
I digest, uno accanto all'altro
Fai passare la stringa «hello» attraverso ogni algoritmo e le differenze saltano subito all'occhio. MD5 dà 5d41402abc4b2a76b9719d911017c592, trentadue caratteri esadecimali per 128 bit. SHA-1 dà aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d, quaranta caratteri per 160 bit. SHA-256 dà 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824, sessantaquattro caratteri per 256 bit. Ogni carattere esadecimale porta quattro bit, quindi la lunghezza in caratteri è sempre la lunghezza in bit divisa per quattro — un modo rapido per identificare un hash non etichettato in un log o in una colonna di database.
Ora aggiungi un semplice punto. sha256("hello.") è 1589999b0ca6ef8814283026a9f166d51c70a910671c3d44049755f07f2eb910 — nemmeno un carattere in comune con il digest di "hello" in una posizione prevedibile. È l'effetto valanga, e vale con la stessa forza in MD5, il cui digest per "hello." è d94c10e437d18531e122ed0b45badd2a. Non è la valanga ad aver ceduto. MD5 rimescola ancora benissimo; semplicemente, un attaccante abbastanza abile sa dirigere due rimescolamenti nello stesso punto.
Una falsificazione riproducibile: l'estensione di lunghezza
MD5, SHA-1, SHA-256 e SHA-512 condividono tutti la costruzione di Merkle-Damgard: il messaggio viene riempito, diviso in blocchi fissi, e ogni blocco aggiorna uno stato interno corrente. Il digest che pubblichi è quello stato interno. Il che significa che chiunque abbia il tuo digest può ricaricarlo nell'algoritmo e continuare a fare hash, come se fosse stato lì dall'inizio. È la proprietà di estensione di lunghezza, e non è un difetto di nessuna di queste funzioni — è ciò che la costruzione fa.
Eccola eseguita. Prendi un tag di autenticazione ingenuo costruito come sha256(segreto + messaggio), con un segreto da 32 byte e il messaggio user=alice&role=viewer. Il tag legittimo comincia con 0556f5e825e91626. Un attaccante che conosce solo il messaggio, il tag e la lunghezza del segreto — non il segreto — può riprendere SHA-256 da quel tag, aggiungere i dieci byte di riempimento 800000000000000001b0 che l'hashing originale avrebbe inserito, poi aggiungere &role=admin. Il tag che ne esce è cca75089ae751c4359a577329d74d9ba345ed7e5f83f988583b2baa16cad5efe, ed è byte per byte il digest che il server calcola sul messaggio esteso. La falsificazione verifica. Il segreto non è mai stato conosciuto.
La correzione non è un digest più lungo né un'altra variante di SHA-2. È HMAC, che annida l'hash due volte con due chiavi derivate, così il tag pubblicato non è più uno stato interno riprendibile. HMAC-SHA-256 sulla stessa chiave e lo stesso messaggio dà 2ad69479d608c0fc4c89387db138aebb0bbee3b35d46057726228cacfc8a1478, e nessuna aggiunta ne produce un'estensione valida. SHA-3 è immune per un altro motivo: la sua costruzione a spugna emette solo una parte dello stato interno, quindi il digest non rivela dove si trovava l'algoritmo.
Nessuno di questi è un hash per password
È l'errore che costa di più, e non ha nulla a che vedere con le collisioni. Gli hash generici sono progettati per il throughput, e lo mantengono. Misurato su un singolo core con un buffer da 64 MB, MD5 corre a 632 MB/s, SHA-256 a 1 075 MB/s e SHA-1 a 1 357 MB/s. L'ordine merita un secondo sguardo: qui SHA-256 è il 70 % più veloce di MD5, perché i processori moderni includono istruzioni SHA dedicate e nessuna istruzione MD5. «MD5 è più veloce» ha smesso di essere affidabile anni fa.
La velocità è esattamente la proprietà sbagliata per una password memorizzata, perché l'attaccante che ha il tuo database ne trae molto più vantaggio di te. Tu fai l'hash di una password per accesso; lui ne fa miliardi al secondo su un rack di GPU. Le funzioni di hash per password ribaltano quel patto di proposito. Sulla stessa macchina, PBKDF2-SHA-256 a 600 000 iterazioni impiega 148 millisecondi per password, e scrypt con N = 131 072 ne impiega 397. Sono circa sette password al secondo invece di milioni — una zavorra deliberata che tu paghi una volta per accesso e l'attaccante una volta per tentativo.
Quindi la risposta corretta alla domanda «quale hash per le password» è: nessuno di quelli in questo articolo. Usa Argon2id quando puoi scegliere liberamente, bcrypt quando la piattaforma non ti dà altro, scrypt o PBKDF2 quando uno standard li impone, sempre con un salt casuale unico per utente. SHA-256 conserva il suo posto dentro quelle costruzioni — PBKDF2-SHA-256 vi si appoggia — ma è la primitiva, non lo schema.
SHA-3 non è un SHA-2 più grande
La numerazione invita alla conclusione sbagliata. SHA-2 è succeduto a SHA-1 come progetto migliorato della stessa linea; SHA-3 non è succeduto a SHA-2 in quel senso, per nulla. È uscito da un concorso aperto che il NIST ha condotto dal 2007, è stato vinto dal team Keccak ed è stato standardizzato in FIPS 202 nel 2015 — mentre SHA-2 restava perfettamente sano, e lo resta. Il NIST non ha mai chiesto a nessuno di abbandonare SHA-2.
Il senso di SHA-3 è la diversità architetturale. Essendo una spugna e non una catena di Merkle-Damgard, un attacco che rompesse SHA-2 molto probabilmente non lo toccherebbe, e il mondo avrebbe un sostituto pronto. La spugna elimina inoltre gratis l'estensione di lunghezza, ragione per cui alcuni progetti la preferiscono già oggi. Il suo costo è la velocità: SHA3-256 ha misurato 317 MB/s sullo stesso hardware su cui SHA-256 ha toccato 1 075 MB/s, in buona parte perché l'hardware accelera l'uno e non l'altro. Scegli SHA-3 quando vuoi la costruzione diversa, non quando vuoi più bit — SHA3-256 e SHA-256 offrono gli stessi 256.
Una breve lista di decisione
Firmare qualsiasi cosa, verificare un download proveniente da una rete ostile, costruire un albero di Merkle, derivare un indirizzo di contenuto: SHA-256. Conservare una password o derivarne una chiave: Argon2id, bcrypt o scrypt, mai un hash nudo. Autenticare un messaggio con un segreto condiviso: HMAC-SHA-256, non sha256(segreto + messaggio), per la ragione dimostrata sopra. Deduplicare file, indicizzare una cache, ripartire una tabella hash, individuare un trasferimento troncato: MD5 va ancora bene ed è ancora abbastanza veloce, purché nessuno nel quadro tragga vantaggio da una collisione.
Un solo test risolve i casi dubbi. Chiediti se chi trae vantaggio dal fatto che due input condividano un digest può anche scegliere quegli input. Se la risposta è no — un guasto del disco, un cavo ballerino, un caricamento parziale —, una resistenza alle collisioni rotta non ti costa nulla. Se la risposta è sì, o potrebbe diventarlo appena il dato lascia la tua macchina, ti serve un hash con la resistenza alle collisioni intatta, e questo significa SHA-256 o meglio.
| Algoritmo | Digest | Resistenza alle collisioni | Resistenza alla preimmagine | Uso ragionevole nel 2026 |
|---|---|---|---|---|
| MD5 | 128 bit, 32 caratteri esadecimali | Rotta dal 2004; collisioni in pochi secondi | Ancora intatta | Checksum non avversariali, chiavi di cache, deduplicazione |
| SHA-1 | 160 bit, 40 caratteri esadecimali | Rotta dal 2017 (2^63 valutazioni) | Ancora intatta | Solo compatibilità legacy; nessuna firma nuova |
| SHA-256 | 256 bit, 64 caratteri esadecimali | Intatta; il miglior attacco è generico, 2^128 | Intatta, 2^256 | Il default per firme, integrità, commitment |
| SHA-512 | 512 bit, 128 caratteri esadecimali | Intatta, 2^256 | Intatta, 2^512 | Stessa famiglia di SHA-256; più veloce in software a 64 bit senza istruzioni SHA |
| SHA3-256 | 256 bit, 64 caratteri esadecimali | Intatta; costruzione diversa (spugna Keccak) | Intatta; immune all'estensione di lunghezza | Un'assicurazione strutturale contro una futura rottura di SHA-2, non più robustezza |
Domande frequenti
- È sicuro usare MD5 nel 2026?
- Solo dove nessun avversario tragga vantaggio da una collisione. MD5 ha perso la resistenza alle collisioni nel 2004 e oggi una collisione richiede secondi, quindi ogni uso in cui qualcuno guadagni facendo condividere un digest a due input diversi — firme, certificati, controlli di integrità su una rete non fidata, deduplicazione di file forniti dall'attaccante — non è sicuro. Gli usi la cui unica minaccia è l'incidente restano validi: verificare che una copia non sia stata troncata, indicizzare una cache, ripartire dati fra server, confrontare backup locali. MD5 non ha perso la resistenza alla preimmagine, quindi un digest pubblicato non rivela nemmeno il suo input. La regola pragmatica: MD5 è un'impronta veloce, non un controllo di sicurezza. E non è nemmeno più l'opzione più veloce: misurato su un core, SHA-256 ha girato a 1 075 MB/s contro i 632 MB/s di MD5, perché i processori portano istruzioni SHA. Se la velocità era il tuo motivo, è scaduto.
- Un hash SHA-256 può essere decifrato o invertito?
- No, e la parola decifrare non si applica — fare hash non è cifrare, perché non c'è chiave né via di ritorno prevista. SHA-256 mappa input di qualsiasi lunghezza su 256 bit, quindi infiniti input condividono ogni digest e l'originale non può essere isolato nemmeno in linea di principio. Recuperare un input significa forza bruta: indovinare candidati e fare l'hash di ciascuno finché uno coincide. È per questo che i cosiddetti siti di «rottura di hash» funzionano. Non invertono nulla; conservano tabelle precalcolate di digest di input comuni e cercano il tuo. Contro un valore casuale da 32 byte la ricerca fallisce e restano 2^256 tentativi. Contro la stringa «password» riesce all'istante. Conseguenza pratica: il digest di un segreto a bassa entropia è appena un segreto, che è esattamente il motivo per cui la conservazione delle password aggiunge un salt per utente (contro le tabelle condivise) e una funzione deliberatamente lenta (contro l'indovinare rapido).
- Dovrei usare SHA-512 invece di SHA-256 per più sicurezza?
- Raramente ne vale la pena. SHA-256 offre 128 bit di resistenza alle collisioni e 256 di resistenza alla preimmagine; SHA-512 raddoppia entrambi, a 256 e 512. Poiché nessun attacco contro SHA-256 si avvicina a 2^128, il margine in più non compra nulla di indicabile, mentre il digest raddoppia a 128 caratteri esadecimali in ogni colonna, URL e riga di log che deve trasportarlo. Ci sono due ragioni reali per scegliere SHA-512. Le prestazioni in software a 64 bit senza accelerazione SHA hardware, dove le parole a 64 bit di SHA-512 possono superare SHA-256 — anche se su hardware che accelera SHA-256 l'ordine si rovescia, come qui, 1 075 MB/s contro 516 MB/s. E una specifica che lo imponga. SHA-512/256, variante troncata definita in FIPS 180-4, dà la velocità delle parole a 64 bit con output da 256 bit ed è il compromesso più pulito quando ti servono entrambe le cose.
- Perché non posso semplicemente fare l'hash delle password con SHA-256 e un salt?
- Un salt risolve un problema e lascia intatto quello più grande. Blocca le tabelle precalcolate e costringe l'attaccante ad attaccare ogni account separatamente — cosa di valore reale. Ciò che non può cambiare è il costo per tentativo. SHA-256 è costruito per essere economico, e un attaccante con il tuo database salato attacca ogni account al ritmo che il suo hardware consente, che su un rack di GPU è enorme. La difesa deve rendere costoso ogni singolo tentativo, ed è quello che fa una funzione di hash per password. Misurato qui, PBKDF2-SHA-256 a 600 000 iterazioni costa 148 ms per password e scrypt a N = 131 072 costa 397 ms; Argon2id aggiunge sopra un costo di memoria, così una GPU non può semplicemente eseguire migliaia di istanze in parallelo. Salt e lentezza servono entrambi, e solo la seconda dipende dall'algoritmo che scegli. Usa Argon2id, bcrypt o scrypt e lascia SHA-256 al loro interno, dove gli spetta.
- Che cos'è l'estensione di lunghezza e mi riguarda?
- Ti riguarda solo se hai costruito un tag di autenticazione come hash(segreto + messaggio). Poiché MD5, SHA-1 e la famiglia SHA-2 pubblicano il loro stato interno sotto forma di digest, chiunque abbia quel digest può riprendere il calcolo e produrre un tag valido per il messaggio con dati aggiunti in coda, senza mai venire a conoscenza del segreto. Non è teorico: partendo da un tag reale su un segreto da 32 byte e user=alice&role=viewer, aggiungendo i dieci byte di riempimento 800000000000000001b0 e poi &role=admin, esce cca75089ae751c4359a577329d74d9ba345ed7e5f83f988583b2baa16cad5efe, esattamente ciò che il server calcola. Poiché i parser di query prendono di solito l'ultima occorrenza di una chiave ripetuta, quell'estensione ribalta il ruolo. Due correzioni funzionano: usare HMAC, progettato per l'autenticazione a chiave e non estendibile, oppure usare SHA-3, la cui spugna non espone mai lo stato completo. Se stai semplicemente facendo l'hash di un file senza alcun segreto, l'estensione di lunghezza non ti tocca.
- Devo migrare da SHA-2 a SHA-3?
- No. Il NIST ha standardizzato SHA-3 in FIPS 202 come alternativa, non come sostituto, e continua ad approvare la famiglia SHA-2 in FIPS 180-4 senza alcuna deprecazione in vista. SHA-3 esiste perché dipendere da una sola costruzione è un rischio sistemico: SHA-1 e SHA-2 condividono una linea progettuale, quindi una svolta contro l'uno ha destato ragionevole preoccupazione per l'altro. La spugna di Keccak è un meccanismo del tutto diverso, ed è tutto il punto. Ricorri a SHA-3 in tre situazioni. Quando un protocollo o un regolatore lo impone. Quando vuoi l'immunità all'estensione di lunghezza senza avvolgere tutto in HMAC. Quando progetti qualcosa destinato a sopravvivere all'attuale consenso crittografico e vuoi diversità di costruzione. Per il resto SHA-256 resta il default sensato, ed è di solito più veloce perché i processori lo accelerano: qui 1 075 MB/s contro 317 MB/s di SHA3-256. Nota inoltre che il livello di sicurezza è identico — SHA3-256 e SHA-256 danno entrambi digest da 256 bit e 128 bit di resistenza alle collisioni.
Articoli che potrebbero interessarti
Tutte le guide →Strumenti correlati
Fonti
- NIST — FIPS 180-4, Secure Hash Standard (SHS)
- NIST — FIPS 202, SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
- NIST — SP 800-131A Rev. 2, Transitioning the Use of Cryptographic Algorithms and Key Lengths
- CWI Amsterdam and Google Research — SHAttered: the first SHA-1 collision
- IETF — RFC 6151, Updated Security Considerations for MD5 and HMAC-MD5
- OWASP — Password Storage Cheat Sheet
Hai notato un errore in questo articolo?