MD5 vs SHA-256 vs SHA-512 — Funzioni Hash Spiegate
Le funzioni hash sono ovunque nello sviluppo software: verifica dell'integrità dei file, archiviazione delle password, firme digitali, autenticazione API, chiavi di cache, deduplicazione. Eppure la maggior parte degli sviluppatori le usa come scatole nere — inserisci una stringa, ottieni un digest hex di lunghezza fissa. I dettagli su quale funzione hash usare, e quale evitare, si rivelano di grande importanza.
MD5 è compromesso. SHA-1 è deprecato. SHA-256 e SHA-512 sono attualmente sicuri. SHA-3 esiste se vuoi un'ulteriore protezione per il futuro. Ma "compromesso" non significa la stessa cosa in ogni contesto — MD5 va bene per alcuni casi d'uso e è disastrosamente sbagliato per altri. Questa guida spiega le proprietà che contano, come ogni funzione si comporta rispetto a esse, e fornisce un chiaro framework decisionale per scegliere l'hash giusto nel 2026.
Cosa Fa Davvero una Funzione Hash
Una funzione hash crittografica mappa un input di lunghezza arbitraria a un output di lunghezza fissa (il digest o hash). Tre proprietà definiscono una funzione hash crittograficamente sicura:
- Resistenza alla preimmagine — dato un hash
h, dovrebbe essere computazionalmente infattibile trovare qualsiasi inputmtale chehash(m) = h. Questa è la proprietà "unidirezionale". - Resistenza alla seconda preimmagine — dato un input
m1, dovrebbe essere infattibile trovare un input diversom2tale chehash(m1) = hash(m2). - Resistenza alle collisioni — dovrebbe essere infattibile trovare qualsiasi due input distinti
m1em2tali chehash(m1) = hash(m2).
Una funzione che fallisce una qualsiasi di queste proprietà è considerata compromessa per uso crittografico. Nota che "infattibile" ha un significato specifico qui: non significa matematicamente impossibile, significa richiedere più computazione di quanto sia pratico con l'hardware attuale o prevedibile.
Inoltre, le funzioni hash crittografiche esibiscono l'effetto valanga: cambiare un singolo bit nell'input produce un output che differisce in circa metà dei suoi bit. Questo garantisce che input simili producano digest completamente diversi.
Input: "hello"
MD5: 5d41402abc4b2a76b9719d911017c592 (128-bit / 32 caratteri hex)
Input: "Hello"
MD5: 8b1a9953c4611296a827abf8c47804d7 (un carattere cambiato = output completamente diverso) MD5 — Veloce, Ubiquo e Compromesso
Storia e design
MD5 (Message Digest 5) è stato progettato da Ron Rivest nel 1991 e produce un digest da 128 bit (16 byte). Per la maggior parte degli anni '90 era la scelta standard per la verifica dell'integrità dei file, la firma dei certificati e l'hashing delle password. È estremamente veloce — una CPU moderna può calcolare decine di milioni di hash MD5 al secondo, e una GPU può calcolarne miliardi.
Perché MD5 è compromesso
Nel 2004, Xiaoyun Wang e colleghi hanno dimostrato un attacco di collisione pratico contro MD5 — due file diversi che producono lo stesso hash MD5. L'attacco gira in minuti sull'hardware consumer. Nel 2008, i ricercatori hanno creato un certificato CA canaglia usando una collisione MD5, dimostrando che la reale infrastruttura PKI era vulnerabile. Entro il 2012, il malware Flame ha usato una collisione MD5 per falsificare un certificato di firma del codice Microsoft.
Il NIST ha ufficialmente deprecato MD5 per la maggior parte degli usi crittografici. Le autorità di certificazione hanno smesso di emettere certificati firmati con MD5 entro il 2009. I vendor di browser hanno rimosso il supporto per le firme di certificati MD5 intorno al 2011.
Quando MD5 è ancora accettabile
MD5 non è universalmente inutile. Per checksum non di sicurezza — rilevare la corruzione accidentale dei dati nei trasferimenti di file, l'indirizzamento basato sul contenuto in un sistema di cache dove l'attaccante non può influenzare gli input, o la generazione di identificatori univoci in un sistema interno chiuso — MD5 rimane adeguato. Il test chiave: se un attaccante può trarre vantaggio dalla creazione di una collisione, non usare MD5. Se conta solo la corruzione accidentale, MD5 va bene.
- Sicuro: deduplicazione interna, chiavi di cache, rilevamento di modifiche ai file non di sicurezza
- Non sicuro: certificati, firme digitali, hashing delle password, verifica dell'autenticità dei file, token di sicurezza
SHA-1 — Deprecato, Non Ancora Morto
SHA-1 produce un digest a 160 bit ed era il successore di MD5. È rimasto lo standard per la firma dei certificati e la firma del codice per la maggior parte degli anni 2000. Nel 2017, l'attacco SHAttered ha dimostrato la prima collisione pratica di SHA-1, producendo due file PDF diversi con hash SHA-1 identici usando circa 110 anni-GPU di computazione — costoso ma alla portata di budget statali e sempre più accessibile.
SHA-1 è deprecato dal NIST e da tutte le principali autorità di certificazione. Non dovrebbe essere usato per certificati, firma del codice o qualsiasi nuova applicazione sensibile alla sicurezza. Alcuni sistemi legacy usano ancora SHA-1 internamente, ma la migrazione a SHA-256 è fortemente raccomandata.
SHA-256 — Lo Standard Attuale
SHA-256 fa parte della famiglia SHA-2, progettata dalla NSA e standardizzata dal NIST in FIPS 180-4. Produce un digest da 256 bit (32 byte). SHA-256 è stato analizzato intensamente dalla sua pubblicazione nel 2001 e non è stato trovato nessun attacco pratico. È lo standard de facto per:
- Certificati TLS (essenzialmente tutti i certificati emessi oggi usano SHA-256)
- Firma del codice (Windows Authenticode, notarizzazione Apple, JAR)
- HMAC-SHA256 per l'autenticazione API (AWS Signature v4, verifica webhook GitHub)
- Firme dei token JWT (HS256 e RS256 usano entrambi SHA-256 internamente)
- ID di transazione blockchain (Bitcoin usa double-SHA256)
- Verifica dell'integrità dei file nei package manager (npm, pip, apt)
Input: "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
(256-bit / 64 caratteri hex)
SHA-512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d
99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
(512-bit / 128 caratteri hex) Prestazioni di SHA-256
SHA-256 usa operazioni su parole a 32 bit internamente. Su hardware a 32 bit o CPU più vecchie senza accelerazione hardware, è notevolmente più lento di MD5. Su CPU moderne a 64 bit con estensioni SHA (Intel Goldmont+, AMD Zen+, Apple Silicon, ARM Cortex-A57+), SHA-256 è accelerato via hardware ed estremamente veloce — spesso si avvicina alla velocità di MD5. La maggior parte degli ambienti server ha accelerazione hardware, quindi in pratica SHA-256 è abbastanza veloce per praticamente tutte le applicazioni.
SHA-512 — Più Ampio, a Volte Più Veloce
SHA-512 produce un digest da 512 bit (64 byte) usando operazioni su parole a 64 bit internamente. Su hardware a 64 bit senza estensioni SHA, SHA-512 può effettivamente essere più veloce di SHA-256 perché le sue operazioni a 64 bit fanno un uso migliore delle larghezze di registro moderne. Su hardware con estensioni SHA, SHA-256 è tipicamente più veloce perché le estensioni sono ottimizzate specificamente per SHA-256.
SHA-512 fornisce un margine di sicurezza maggiore — resistenza alle collisioni a 256 bit contro 128 bit per SHA-256. Per la maggior parte dei modelli di minaccia attuali, la resistenza alle collisioni a 128 bit di SHA-256 è più che sufficiente. SHA-512 è appropriato quando:
- Stai puntando a server a 64 bit e vuoi il massimo throughput senza estensioni hardware
- Hai bisogno di digest più lunghi come materiale chiave per altre operazioni crittografiche
- Vuoi un margine di sicurezza aggiuntivo per i dati che devono rimanere protetti per decenni
- Stai implementando protocolli che richiedono specificamente SHA-512
SHA-384 e SHA-512/256
SHA-384 è una versione troncata di SHA-512 che produce 384 bit — utile quando vuoi le operazioni interne a 64 bit di SHA-512 ma hai bisogno di output più breve. SHA-512/256 è un'altra variante troncata che produce output a 256 bit usando il calcolo interno di SHA-512. SHA-512/256 è resistente agli attacchi di estensione della lunghezza che colpiscono SHA-256, rendendolo utile in contesti dove l'estensione della lunghezza è un problema (anche se HMAC già mitiga questo nella maggior parte degli scenari pratici).
SHA-3 — Architettura Diversa, a Prova di Futuro
SHA-3 (standardizzato in NIST FIPS 202, 2015) usa la costruzione a spugna Keccak — un design fondamentalmente diverso dalla struttura Merkle-Damgard di SHA-2. Questo è importante perché qualsiasi debolezza futura scoperta nel design Merkle-Damgard colpirebbe MD5, SHA-1 e SHA-2 simultaneamente, mentre SHA-3 rimarrebbe inalterato.
SHA-3 è attualmente sicuro ed è la scelta giusta per i nuovi sistemi che necessitano di garanzie a lungo termine o che vogliono proteggersi contro future debolezze di SHA-2. È più lento di SHA-256 nelle implementazioni software pure. Dove SHA-3 brilla è nelle implementazioni hardware — il suo design è molto efficiente nel silicio.
Tabella di Confronto
| Algoritmo | Output | Resist. collisioni | Stato | Velocità (SW) | Per password? |
|---|---|---|---|---|---|
| MD5 | 128-bit | Compromessa | Deprecato | Molto veloce | Mai |
| SHA-1 | 160-bit | Compromessa | Deprecato | Veloce | Mai |
| SHA-256 | 256-bit | 128-bit | Standard attuale | Veloce (HW accel) | Mai (troppo veloce) |
| SHA-512 | 512-bit | 256-bit | Sicuro | Veloce su 64-bit | Mai (troppo veloce) |
| SHA-3-256 | 256-bit | 128-bit | A prova di futuro | Moderata (SW) | Mai (troppo veloce) |
| bcrypt | stringa 60 char | N/D | Solo password | Intenzionalmente lento | Sì |
Hashing delle Password: Un Problema Completamente Diverso
Questo merita una sezione a parte perché è uno degli errori più comuni che fanno gli sviluppatori. SHA-256 è lo strumento giusto per le verifiche di integrità dei file, la firma API e la verifica dei certificati. È lo strumento sbagliato per l'hashing delle password, e usarlo per questo scopo causa veri incidenti di sicurezza.
Il problema è la velocità. SHA-256 è progettato per essere veloce — una GPU moderna può calcolare miliardi di hash SHA-256 al secondo. Un attaccante che ottiene il tuo database di password con hash può tentare miliardi di ipotesi di password al secondo. Anche una password lunga e casuale può essere violata rapidamente se l'hash è veloce.
// NON fare mai questo per le password
const hash = crypto.createHash('sha256').update(password).digest('hex'); // Usa bcrypt, scrypt o Argon2 per le password
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); // fattore di costo 12 Lo strumento Bcrypt Test ti permette di eseguire l'hash e verificare le password bcrypt nel browser. Per capire i fattori di costo di bcrypt e i loro tempi di calcolo, è un riferimento utile quando configuri il fattore di lavoro della tua applicazione.
HMAC: Aggiungere Autenticazione a un Hash
Un semplice hash non prova nulla su chi lo ha calcolato — chiunque abbia i dati può calcolare lo stesso hash SHA-256. HMAC (Hash-based Message Authentication Code) aggiunge una chiave segreta al calcolo, producendo un tag che può essere riprodotto solo da chi conosce la chiave. HMAC-SHA256 è lo standard per:
- Verifica della firma dei webhook (GitHub, Stripe, Shopify usano tutti HMAC-SHA256)
- AWS Signature Version 4 (firma delle richieste)
- Token JWT HS256 (HMAC-SHA256 di header + payload)
- Integrità dei cookie (firma dei cookie di sessione per prevenire manomissioni)
const crypto = require('crypto');
// Firma un messaggio con HMAC-SHA256
const mac = crypto
.createHmac('sha256', secretKey)
.update(message)
.digest('hex');
// Verifica: confronta in tempo costante (previene attacchi di timing)
const isValid = crypto.timingSafeEqual(
Buffer.from(mac, 'hex'),
Buffer.from(received, 'hex')
);
Nota l'uso di timingSafeEqual per il confronto. Confrontare i valori MAC con un normale controllo di uguaglianza delle stringhe rivela informazioni di timing che possono essere sfruttate in un attacco di timing. Usa sempre una funzione di confronto a tempo costante quando verifichi i MAC. Usa il Generatore HMAC per calcolare valori HMAC-SHA256 per test e debug senza scrivere codice.
Raccomandazioni Pratiche
Integrità generale dei file (checksum)
Usa SHA-256. È lo standard per la verifica dei pacchetti (lockfile npm, hash dei requisiti pip, layer delle immagini Docker). Lo strumento SHA-256 Hash calcola i digest SHA-256 nel tuo browser per input di testo o valori di stringa. Per checksum non di sicurezza veloci dove la velocità è critica e ti fidi della fonte, MD5 rimane accettabile ma SHA-256 è preferibile in qualsiasi contesto condiviso o automatizzato.
Certificati TLS e firma del codice
SHA-256 è lo standard richiesto. Tutte le autorità di certificazione emettono certificati SHA-256. Non usare mai MD5 o SHA-1 per i nuovi certificati — saranno rifiutati dai browser e dai sistemi operativi moderni.
Autenticazione API
Usa HMAC-SHA256. È lo standard consolidato, ben supportato in tutti i linguaggi. Calcola i digest con lo strumento MD5 Hash o SHA-256 Hash per confronti rapidi, e genera firme HMAC con il Generatore HMAC.
Hashing delle password
Usa bcrypt (fattore di costo 12+), scrypt o Argon2id. Non usare mai MD5, SHA-1, SHA-256 o SHA-512 direttamente per le password, neanche con salting. Lo strumento Bcrypt Test può aiutarti a verificare gli hash bcrypt durante lo sviluppo.
Dati longevi che richiedono decenni di sicurezza
Preferisci SHA-512 o SHA-3-256. La dimensione maggiore del digest fornisce un margine aggiuntivo contro i progressi nella crittoanalisi. Il NIST raccomanda SHA-512 e SHA-3 per le applicazioni che richiedono sicurezza a lungo termine. Consulta la guida ufficiale in NIST FIPS 180-4 per la specifica autorevole degli algoritmi SHA-2.
Nuovi sistemi senza vincoli legacy
SHA-256 per uso generale. Argon2id per le password. HMAC-SHA256 per i codici di autenticazione. Se vuoi una protezione per il futuro e puoi accettare prestazioni leggermente inferiori, SHA-3-256 è una solida alternativa a SHA-256 per l'hashing generico.