Password Hashing (bcrypt, Argon2, scrypt)

Indice dei contenuti

    Il password hashing è la pratica di trasformare una password in chiaro in un’impronta crittografica prima di memorizzarla, in modo che in caso di violazione del database le password originali non siano immediatamente recuperabili. Non tutte le funzioni hash sono adatte a questo scopo: le funzioni crittografiche generali come SHA-256 o MD5 sono progettate per essere veloci — una proprietà desiderabile per il calcolo di integrità dei file, ma disastrosa per la protezione delle password, perché permette di eseguire miliardi di tentativi al secondo con hardware comune. I moderni algoritmi di password hashing risolvono questo problema essendo deliberatamente lenti e costosi in memoria.

    Perché SHA-256 non va usato per le password

    SHA-256 su GPU moderna: ~10 miliardi di hash al secondo. Una password di 8 caratteri alfanumerici ha circa 6282×101462^8 \approx 2 \times 10^{14} combinazioni — esauribili in ore. Un database di password hashate con SHA-256 (o peggio, MD5) dopo un breach è effettivamente compromesso nella maggior parte dei casi in pochi giorni con hardware standard e dizionari di password comuni.

    Il secondo problema è la mancanza di salt: se due utenti hanno la stessa password, producono lo stesso hash. Le rainbow table — database precalcolati di hash di password comuni — permettono di invertire l’hash in tempo costante. Il salt (valore casuale aggiunto alla password prima dell’hash) elimina questo vettore rendendo ogni hash unico.

    bcrypt

    Progettato da Niels Provos e David Mazières nel 1999, bcrypt è basato sull’algoritmo di cifratura Blowfish. Introduce un parametro di costo (cost factor) che determina il numero di iterazioni: cost=12 esegue 212=40962^{12} = 4096 round. Aumentare il cost factor di 1 raddoppia il tempo di calcolo — permette di mantenere la resistenza nel tempo all’aumentare della potenza computazionale disponibile.

    Il salt (16 byte casuali) è incorporato nell’output insieme al cost factor e all’hash, in un formato autocontenuto:

    $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/ggDoHBiQ.EfF/U1Xi
     ↑   ↑  ←────── salt (22 char Base64) ──────→←── hash ────→
    versione cost

    Limite di bcrypt: tronca la password a 72 byte — password più lunghe non aggiungono sicurezza. Su GPU moderne rimane ragionevolmente resistente, ma la sua struttura non è memory-hard.

    scrypt

    Progettato da Colin Percival nel 2009 per essere sia time-hard sia memory-hard: richiede una quantità significativa di RAM per essere calcolato, rendendo gli attacchi con ASIC o GPU molto meno efficaci perché questi dispositivi hanno memoria limitata per core. I parametri sono N (costo CPU/memoria), r (fattore di blocco), p (parallelizzazione). Adottato da Litecoin come algoritmo di proof-of-work.

    Argon2

    Vincitore della Password Hashing Competition (2015), Argon2 è l’algoritmo raccomandato da OWASP e dall’IETF (RFC 9106) per le nuove applicazioni. Esistono tre varianti:

    • Argon2d: massima resistenza agli attacchi GPU, vulnerabile a side-channel
    • Argon2i: resistente a side-channel, leggermente meno resistente alla GPU
    • Argon2id: ibrido, combinazione dei due — raccomandata per la maggior parte degli usi

    I parametri configurabili sono: m (memoria in KiB), t (iterazioni), p (parallelismo). OWASP raccomanda come minimo m=19456 (19 MiB), t=2, p=1.

    Raccomandazioni pratiche

    ScenarioAlgoritmo raccomandato
    Nuova applicazioneArgon2id
    Sistemi legacy che supportano solo bcryptbcrypt con cost ≥ 12
    Sistemi con vincoli di memoriascrypt o bcrypt
    Mai usareMD5, SHA-1, SHA-256/512 senza KDF, cifratura reversibile

    Il parametro di costo va calibrato in modo che l’hash di una singola password richieda ~100–300 ms sull’hardware di produzione — abbastanza da rendere il brute force impraticabile, abbastanza poco da non degradare l’esperienza utente in login normali.

    In caso di breach, la lentezza dell’algoritmo è l’unico fattore che guadagna tempo: anche con Argon2id a parametri robusti, password brevi o comuni sono recuperabili. La prima linea di difesa rimane imporre password lunghe o passphrase.

    Ultimo aggiornamento: