Una violazione dei dati che espone le password degli utenti è un disastro con ripercussioni immense. Se le credenziali sono conservate in testo in chiaro – o peggio, "hashate" con algoritmi inadeguati come MD5 o SHA – gli aggressori possono decifrarne milioni in pochissimi istanti. Un hashing delle password correttamente implementato è la tua ultima, e più cruciale, linea di difesa. Questa guida completa ti svelerà quali metodi adottare, le motivazioni dietro tali scelte e le modalità di implementazione più efficaci.
Perché Salvare le Password in Testo in Chiaro È Inaccettabile (e Pericoloso)
Nel malaugurato caso di una violazione del tuo database, se le password fossero memorizzate in testo in chiaro, ogni singola credenziale utente verrebbe immediatamente compromessa. Data la diffusa abitudine degli utenti di riutilizzare le stesse password su piattaforme diverse, una falla nel tuo sistema potrebbe innescare una reazione a catena, esponendo i loro account bancari, email, social media e molti altri servizi sensibili. Una negligenza di questo tipo può distruggere la fiducia e causare danni irreparabili.
MD5 e SHA: Perché Sono Inadeguati per la Protezione delle Password
MD5 e SHA-256 sono algoritmi di hash concepiti per scopi generici. La loro caratteristica distintiva è l'estrema velocità: un moderno processore grafico (GPU) può eseguire miliardi di operazioni di hash SHA-256 al secondo. Questa efficienza, tuttavia, è esattamente l'opposto di ciò che si desidera quando si tratta di proteggere le password, dove la lentezza è una virtù.
Algoritmo Hash al Secondo (GPU) Tempo per decifrare password di 8 caratteri ───────────────────────────────────────────────────────────────────── MD5 200 miliardi Secondi SHA-256 10 miliardi Minuti bcrypt (costo 12) 5,000 Migliaia di anni Argon2id 1,000 Milioni di anni
Quali Caratteristiche Definiranno un Buon Algoritmo di Hashing per Password?
- Lentezza Intenzionale: Deve impiegare tra i 100ms e i 500ms per generare un hash. Abbastanza veloce per un login legittimo, ma proibitivamente lento per attacchi di forza bruta.
- Fattore di Costo Regolabile: Con l'avanzamento tecnologico e l'aumento della potenza di calcolo, è fondamentale poter incrementare il "costo" computazionale dell'hashing per mantenere la protezione adeguata.
- Salt Integrato: Ogni password deve essere abbinata a un "salt" casuale e univoco prima dell'hashing, garantendo che anche password identiche producano hash completamente diversi, rendendo inutili le rainbow tables.
- "Memory-Hard" (Moderno): Richiede una quantità significativa di memoria RAM per ogni operazione di hashing, rendendo gli attacchi basati su GPU estremamente costosi e poco pratici.
I Giganti dell'Hashing: bcrypt, scrypt e Argon2
bcrypt (1999) - Lo Standard Collaudato
Per quasi due decenni, bcrypt ha rappresentato lo standard de facto nel settore. Progettato per essere "CPU-hard" (intensivo per la CPU), pur non essendo "memory-hard", rimane un'opzione eccellente e ampiamente supportata, dimostrando la sua robustezza nel tempo.
import bcrypt from 'bcryptjs';
// Effettua l'hashing di una password (fattore di costo 12 — impiega circa 300ms)
const hash = await bcrypt.hash("userPassword123", 12);
// → "$2b$12$LJ3m4ys3Lz7g..."
// Verifica una password
const isValid = await bcrypt.compare("userPassword123", hash);
// → true
Argon2id (2015 — La Scelta Raccomandata)
Vincitore della prestigiosa Password Hashing Competition del 2015, Argon2id rappresenta l'apice degli algoritmi di hashing moderni. È sia "CPU-hard" che "memory-hard", offrendo una resistenza superiore agli attacchi. Per tutti i nuovi progetti, è indiscutibilmente la scelta migliore per garantire la massima sicurezza.
import argon2 from 'argon2';
// Effettua l'hashing di una password
const hash = await argon2.hash("userPassword123", {
type: argon2.argon2id, // Variante raccomandata
memoryCost: 65536, // 64 MB
timeCost: 3, // 3 iterazioni
parallelism: 4 // 4 thread
});
// Verifica
const isValid = await argon2.verify(hash, "userPassword123");
La Funzione Integrata password_hash() di PHP
// Hashing — usa bcrypt di default, Argon2id disponibile da PHP 7.3+
$hash = password_hash("userPassword123", PASSWORD_ARGON2ID);
// Verifica
if (password_verify("userPassword123", $hash)) {
echo "Password corretta!";
}
// Controlla se l'hash necessita di essere rigenerato (es. fattore di costo aumentato)
if (password_needs_rehash($hash, PASSWORD_ARGON2ID)) {
$newHash = password_hash("userPassword123", PASSWORD_ARGON2ID);
// Aggiorna l'hash nel database
}
Cos'è il Salting e Perché È Essenziale?
Il "salt" è una stringa casuale, generata in modo univoco, che viene concatenata alla password prima che questa venga sottoposta all'algoritmo di hashing. Senza l'uso di "salt", tutte le password identiche (ad esempio, "password123") produrrebbero lo stesso hash. Questo permetterebbe agli aggressori di sfruttare "rainbow tables" (tabelle precalcolate) per decifrarle istantaneamente. Grazie al "salt", ogni hash diventa unico, rendendo inefficaci tali attacchi e rafforzando notevolmente la sicurezza.
Ottime Notizie: Gli algoritmi moderni come bcrypt, scrypt e Argon2 gestiscono il processo di "salting" in modo completamente automatico e sicuro. Questo significa che non devi preoccuparti di generare o gestire i "salt" manualmente, semplificando notevolmente l'implementazione.
Le Migliori Pratiche per un Hashing Sicuro
- Adotta Argon2id per tutti i nuovi progetti. Se per qualche motivo Argon2 non fosse disponibile o compatibile, considera bcrypt come la migliore alternativa successiva.
- Non utilizzare MAI algoritmi come MD5, SHA-1 o SHA-256 per l'hashing delle password. Sono irrimediabilmente compromessi per questo scopo.
- Evita assolutamente di implementare una tua logica di hashing personalizzata. Affidati sempre a librerie standard e collaudate, sviluppate da esperti di sicurezza.
- Incrementa periodicamente il fattore di costo (cost factor) degli algoritmi man mano che l'hardware evolve. L'obiettivo è mantenere un tempo di hashing compreso tra 200 e 500ms per operazione.
- Implementa il "rate limiting" sugli endpoint di login. Questo limita il numero di tentativi di accesso falliti in un determinato periodo, mitigando gli attacchi di forza bruta online.
- Supporta i gestori di password (password managers). Evita di imporre limiti massimi di lunghezza delle password inferiori a 64 caratteri, per favorire password complesse e generate automaticamente.
- Valuta l'aggiunta di un "pepper": una chiave segreta aggiuntiva, mescolata con la password prima dell'hashing e conservata in una posizione completamente separata dal database delle password. Offre un ulteriore livello di sicurezza.
Prova i Nostri Strumenti di Codifica Gratuiti
Codifica e decodifica Base64, un formato comune nelle intestazioni di autenticazione HTTP.