Perché un hash lento
Quando un database trapela, gli attaccanti indovinano le password offline contro gli hash memorizzati. Un hash veloce come SHA-256 permette a una singola GPU di provare circa dieci miliardi di tentativi al secondo, il che trasforma la maggior parte delle password scelte da esseri umani in testo in chiaro nel giro di ore. Le funzioni di hash per password sono deliberatamente lente e, nei progetti più recenti, affamate di memoria, così che ogni tentativo costi all’attaccante quanto costa a te, e le migliaia di core di una GPU non aiutino perché condividono troppo poca memoria.
| Funzione | Anno | Regolabile | Consigliato (OWASP 2024) | Da usare quando |
|---|---|---|---|---|
| Argon2id | 2015 | memoria, passate, lane | m=19 MiB, t=2, p=1 (o m=64 MiB, t=3) | Default per i nuovi sistemi. Vincitrice della Password Hashing Competition. |
| scrypt | 2009 | N, r, p | N=2¹⁷, r=8, p=1 | Memory-hard; va bene dove Argon2 non è disponibile. |
| bcrypt | 1999 | costo (2ⁿ round) | costo 10 o più | Ovunque; ancora solida. Tronca a 72 byte. |
| PBKDF2 | 2000 | iterazioni | 600.000 (SHA-256) | Conformità FIPS; non memory-hard, quindi la più debole contro le GPU. |
Leggere una stringa di hash
$2b$12$ + 22 caratteri di salt + 31 di hash: bcrypt, costo 12 (4.096 round). $argon2id$v=19$m=19456,t=2,p=1$salt$hash: Argon2id con i suoi parametri nella stringa, Base64 senza padding. Entrambi i formati contengono tutto il necessario per verificare, quindi puoi alzare il costo nel tempo e ricalcolare l’hash degli utenti al loro prossimo login. scrypt e PBKDF2 non hanno un formato di stringa universale; salt e parametri vengono memorizzati a parte, ed è per questo che il verificatore chiede il salt separatamente.
Scegliere un costo
Punta a circa 100–300 ms per hash sul tuo server. Questa pagina riporta quanto ha impiegato ogni hash nel tuo browser (un portatile decente è paragonabile a un piccolo core di server). Argon2 ai 19 MiB consigliati impiega circa un secondo in JavaScript; le implementazioni native sono diverse volte più veloci.
Cosa non fare
Non usare MD5, SHA-1 o SHA-256 da soli, nemmeno con salt. Non usare un unico salt per tutto il sito. Non pre-hashare con SHA-256 per aggirare il limite di 72 byte di bcrypt a meno di codificare il risultato in Base64 (i byte grezzi possono contenere NUL, al quale bcrypt si ferma). E non incollare password di produzione reali in nessuna pagina web, compresa questa; usa valori di prova.
Domande
È sicuro usare questa pagina con una password reale?
L’hash viene calcolato nel tuo browser e nulla viene trasmesso, ma la regola sensata è trattare ogni pagina web come non fidata per credenziali reali. Usala per generare hash per i fixture di test, per capire i formati e per verificare con password usa e getta.
Perché bcrypt dà un hash diverso ogni volta?
Il salt è casuale a ogni chiamata; viene memorizzato dentro la stringa dell’hash. La verifica lo estrae e ricalcola. Due hash della stessa password sono attesi diversi; entrambi verificano.
Perché la verifica bcrypt fallisce con una password lunga?
bcrypt usa solo i primi 72 byte. Se la password è stata hashata da una libreria che pre-hasha (alcune configurazioni di Django e Passlib), la verifica bcrypt grezza qui non corrisponderà. Controlla anche il prefisso: gli hash $2y$ e $2b$ sono compatibili; $2x$ indica un’implementazione difettosa.
Cosa significano m, t e p in Argon2?
m è la memoria in KiB (19456 = 19 MiB), t è il numero di passate su quella memoria, p è il numero di lane che possono girare in parallelo. La memoria è la manopola principale della sicurezza: è ciò che rende costosi gli attacchi con GPU e ASIC.