🔑 Crittografia

Hashing delle password: bcrypt, scrypt e Argon2 a confronto

Perché le password non si cifrano ma si trasformano con funzioni lente: sale, fattore di costo e differenze tra bcrypt, scrypt, PBKDF2 e Argon2.

Quando ti registri a un servizio online, la tua password dovrebbe essere conservata in una forma che nemmeno il gestore del servizio possa leggere. Non cifrata, perché ciò che è cifrato si può decifrare con la chiave, ma trasformata con una funzione di hashing per password. La differenza tra farlo bene e farlo male emerge il giorno in cui il database viene sottratto: in un caso le password restano protette, nell'altro vengono recuperate in poche ore.

Perché non basta un hash qualsiasi

Una funzione hash è a senso unico: dall'impronta non si risale all'originale. Ma un attaccante non ha bisogno di "invertire" la funzione. Gli basta indovinare: prende una password candidata, ne calcola l'hash e lo confronta con quelli rubati. Se coincidono, ha trovato la password.

Gli hash generici come SHA-256 sono progettati per essere velocissimi. Su schede grafiche moderne se ne calcolano miliardi al secondo. Con un dizionario di password comuni, varianti e combinazioni, gran parte delle password reali cade rapidamente.

Il sale: ogni password diventa unica

Il primo accorgimento è il sale (salt): un valore casuale, diverso per ogni utente, che viene unito alla password prima del calcolo e salvato insieme all'hash.

Il sale risolve due problemi:

  • due utenti con la stessa password hanno hash diversi, quindi non si può capire chi condivide la stessa password;
  • le tabelle precalcolate, come le cosiddette tabelle arcobaleno, diventano inutili, perché andrebbero ricostruite da capo per ogni singolo sale.

Il sale non è segreto: serve solo a rendere unico ogni calcolo. Non rallenta però l'attacco mirato a una singola password.

La lentezza voluta: il fattore di costo

Il secondo accorgimento è rendere il calcolo deliberatamente lento e costoso. Se un utente legittimo deve aspettare un decimo di secondo al momento dell'accesso, non se ne accorge. Un attaccante che deve provare miliardi di combinazioni, invece, vede il suo lavoro moltiplicarsi enormemente.

Le funzioni per password hanno un parametro di costo regolabile, da aumentare nel tempo man mano che l'hardware diventa più veloce.

Le funzioni principali

PBKDF2

Ripete un hash, tipicamente HMAC-SHA256, un numero elevato di volte. È standardizzato e diffuso, ma ha un limite: richiede pochissima memoria, quindi si parallelizza bene su schede grafiche e hardware dedicato. Va usato con un numero di iterazioni molto alto.

bcrypt

Progettato alla fine degli anni Novanta, è stato per molto tempo la scelta predefinita in molti framework. Il suo fattore di costo è esponenziale: ogni incremento di uno raddoppia il tempo di calcolo. Ha una particolarità da conoscere: considera solo i primi 72 byte della password, e ciò che segue viene ignorato.

scrypt

Introduce un'idea importante: essere costoso in memoria, oltre che in tempo. Per calcolare un hash serve una quantità significativa di RAM. Questo rende molto più difficile e costoso costruire hardware specializzato che esegua milioni di tentativi in parallelo.

Argon2

Ha vinto nel 2015 la Password Hashing Competition, una selezione pubblica pensata appositamente per individuare un nuovo standard. Permette di regolare separatamente tempo, memoria e grado di parallelismo. Esistono tre varianti; quella generalmente raccomandata per le password è Argon2id, che combina resistenza agli attacchi con hardware dedicato e a certi attacchi basati sull'osservazione degli accessi in memoria.

Un confronto rapido

Funzione Costo in memoria Note
PBKDF2 Basso Standard diffuso, richiede molte iterazioni
bcrypt Basso e fisso Collaudato, limite di 72 byte
scrypt Alto Buona resistenza all'hardware dedicato
Argon2id Configurabile Scelta consigliata per i nuovi sistemi

Il pepe: un segreto in più

Alcuni sistemi aggiungono un pepe (pepper): un valore segreto, uguale per tutti, che non viene salvato nel database ma in un luogo separato, per esempio un modulo hardware o la configurazione del server. Se viene sottratto solo il database, l'attaccante non può nemmeno iniziare a provare le password. Il pepe è un rinforzo, non un sostituto di sale e lentezza.

Dalla password alla chiave

Le stesse funzioni servono anche per derivare una chiave di cifratura da una password, per esempio quando proteggi un archivio, un gestore di password o la chiave privata di un certificato. Il principio è identico: rendere costoso ogni tentativo di indovinare. Un archivio cifrato con AES-256 ma con una chiave derivata in modo veloce da una password debole è protetto solo quanto quella password.

Cosa conta davvero per l'utente

Anche la migliore funzione di hashing non salva una password come "123456" o il nome del proprio animale domestico seguito dall'anno di nascita: sono tra i primi tentativi di qualsiasi attacco. Una password lunga, generata casualmente e conservata in un gestore di password, unita all'autenticazione a più fattori, rende quasi irrilevante il furto del database di un singolo servizio.

In sintesi

  • Le password si conservano con funzioni di hashing dedicate, non con cifratura né con hash veloci.
  • Il sale rende unico ogni hash e neutralizza le tabelle precalcolate.
  • Il fattore di costo rende ogni tentativo lento e va aumentato nel tempo.
  • Argon2id è la scelta consigliata; scrypt, bcrypt e PBKDF2 restano accettabili se ben configurati.
  • Le stesse funzioni servono a derivare chiavi di cifratura da una password.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche