Bcrypt vs Argon2: quale hash di password nel 2026
Bcrypt e Argon2 sono le due funzioni di hashing di password più utilizzate oggi. Entrambe sono progettate per essere lente e resistenti agli attacchi di forza bruta, a differenza di MD5 o SHA-256 che sono veloci per costruzione. Argon2 ha vinto la Password Hashing Competition nel 2015 ed è oggi la scelta raccomandata da OWASP per le nuove applicazioni. Bcrypt resta un'ottima scelta matura e ampiamente supportata. Questo articolo spiega con precisione le differenze per aiutarti a decidere.
Perché un hash di password è diverso
Un hash crittografico classico come SHA-256 è progettato per essere veloce: si vogliono hashare GB di dati al secondo. Per le password, questa proprietà è un difetto: un attaccante che recupera la tua tabella utenti può testare miliardi di password al secondo su una GPU. Una funzione di hashing di password (PHF, password hashing function) cerca invece di essere:
- Lenta per costruzione, con un parametro di costo regolabile
- Salata, per impedire le rainbow table e gli attacchi paralleli su più account
- Resistente all'hardware specializzato (GPU, FPGA, ASIC) per limitare lo speedup adversarial
Il sale e il parametro di costo sono memorizzati insieme all'hash, in una stringa unica
tipicamente nella forma $algo$params$sale$hash. Ciò permette di aumentare il costo
nel tempo senza forzare la migrazione immediata dei vecchi hash.
Bcrypt: 1999, Blowfish, parametro cost
Bcrypt è stato progettato da Niels Provos e David Mazières per OpenBSD nel
1999. Si basa sull'algoritmo di cifratura Blowfish, di cui sfrutta l'elevato costo di
inizializzazione delle tabelle. Bcrypt espone un solo parametro, cost (o
rounds), che definisce il numero di iterazioni nella forma 2^cost. Aumentare cost
di 1 raddoppia il tempo di calcolo.
Formato di output tipico:
$2y$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
| | | |
| | cost = 12 sel + hash en base64
| variante (2y = openbsd)
algo bcrypt
Bcrypt limita l'input a 72 byte: una password più lunga viene troncata silenziosamente, il che rappresenta una nota insidia. Il rimedio abituale è pre-hashare con SHA-256 e poi codificare in base64 prima di bcrypt, ma questo può introdurre null byte problematici in alcune implementazioni. Argon2 non ha questo limite.
Argon2: 2015, vincitore PHC, 3 varianti
Argon2 è stato progettato da Alex Biryukov, Daniel Dinu e Dmitry Khovratovich. Ha vinto la Password Hashing Competition nel luglio 2015 ed è standardizzato dalla RFC 9106 (2021). Argon2 espone tre parametri:
- Memory cost (
m): quantità di memoria utilizzata, in KiB - Time cost (
t): numero di iterazioni sul blocco di memoria - Parallelism (
p): numero di thread paralleli
Argon2 esiste in tre varianti:
- Argon2d: accesso alla memoria dipendente dai dati. Più resistente agli attacchi GPU, ma sensibile agli attacchi side-channel (timing, cache).
- Argon2i: accesso alla memoria indipendente dai dati. Resistente ai side-channel, leggermente meno resistente agli attacchi GPU.
- Argon2id: ibrido, parte in modalità i e poi passa in modalità d. Raccomandato di default da RFC 9106 e OWASP.
I parametri raccomandati da OWASP nel 2026 per Argon2id: m=19456 KiB (19 MiB),
t=2, p=1. Formato di output tipico:
$argon2id$v=19$m=19456,t=2,p=1$c2VsX2FsZWF0b2lyZQ$aGFzaF9jYWxjdWxl
| | | | |
| | parametres sel base64 hash base64
| version
algo argon2id
Perché Argon2id è raccomandato
La resistenza all'hardware specializzato è oggi il criterio decisivo. Bcrypt usa poca memoria (~4 KiB), il che permette a una GPU di fascia alta di testare centinaia di migliaia di hash al secondo. Argon2id è memory-hard: forzare diversi MiB di memoria per tentativo riduce drasticamente il parallelismo raggiungibile su GPU e rende la progettazione di ASIC dedicati economicamente non redditizia.
La modalità ibrida di Argon2id offre inoltre una protezione contro gli attacchi side-channel durante la prima metà del calcolo. È questa combinazione che giustifica il suo posto come raccomandazione di default di OWASP, di NIST SP 800-63B (dalla revisione 2024) e della RFC 9106.
Tabella comparativa
| Criterio | Bcrypt | Argon2id |
|---|---|---|
| Anno | 1999 | 2015 |
| Standardizzazione | De facto, USENIX 1999 | RFC 9106 (2021) |
| Parametri | cost | memory, time, parallelism |
| Memoria utilizzata | ~4 KiB | Configurabile (~19 MiB raccomandato) |
| Memory-hard | No | Sì |
| Resistenza GPU | Moderata | Forte |
| Resistenza side-channel | Buona (constant-time) | Buona (modalità id) |
| Limite di input | 72 byte | Nessuno |
| Raccomandazione OWASP 2026 | Accettabile | Preferito |
| Maturità ecosistema | Molto ampia | Ampia dal ~2018 |
Prestazioni e resistenza agli attacchi
Su un server moderno, un bcrypt a cost=12 impiega circa 250 ms e un argon2id con i parametri OWASP circa 100-300 ms a seconda della macchina. Il tempo assoluto non è il criterio: ciò che conta è il rapporto tra il tuo costo (un calcolo, una volta per login) e quello dell'attaccante (miliardi di calcoli su GPU per craccare un dump).
Su una RTX 4090, hashcat raggiunge circa 200.000 bcrypt/s a cost=12, contro qualche decina di migliaia di argon2id a 19 MiB. A parità di tempo di calcolo lato server, Argon2id rallenta l'attaccante da 5 a 10 volte di più rispetto a bcrypt, e il divario si amplia con le nuove generazioni di GPU.
Esempi PHP
PHP supporta entrambi nativamente tramite password_hash() e
password_verify() da PHP 7.2 per Argon2i (e 7.3 per Argon2id). Il costruttore PHP
gestisce sale e formato automaticamente.
Bcrypt
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$ok = password_verify($password, $hash);
if (password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12])) {
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
}
Argon2id
$opts = [
'memory_cost' => 19456, // 19 MiB
'time_cost' => 2,
'threads' => 1,
];
$hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
$ok = password_verify($password, $hash);
if (password_needs_rehash($hash, PASSWORD_ARGON2ID, $opts)) {
$hash = password_hash($password, PASSWORD_ARGON2ID, $opts);
}
Puoi generare o identificare hash di qualsiasi tipo con il nostro generatore di hash e il nostro identificatore di hash.
Raccomandazione
Per una nuova applicazione nel 2026, scegli Argon2id con i parametri OWASP
come baseline (m=19456, t=2, p=1), da regolare in base
al tempo target (tipicamente da 250 a 500 ms). Se gestisci un'applicazione esistente in
bcrypt, non c'è urgenza di migrare: bcrypt a cost=12 o superiore resta sicuro nel 2026.
Approfitta di un password_needs_rehash() al prossimo login per migrare
progressivamente gli utenti attivi verso Argon2id.
Evita assolutamente MD5, SHA-1 e SHA-256 nudo per le password (vedi il nostro comparativo MD5 vs SHA-256). Nessuno di questi algoritmi è progettato per questo uso.
Domande frequenti
Bcrypt è ancora sicuro nel 2026?
Sì, a condizione di usare un cost sufficiente (minimo 12, 14 se possibile). Bcrypt non ha una vulnerabilità crittografica nota. La sua unica debolezza relativa rispetto ad Argon2id è la sua bassa impronta in memoria, che lo rende più accessibile agli attacchi GPU e FPGA.
Bisogna migrare una base bcrypt verso Argon2id?
Non con urgenza. Una migrazione progressiva con password_needs_rehash() è
l'approccio raccomandato: a ogni login riuscito, ri-hashi la password in Argon2id. Dopo
qualche mese, la maggior parte degli utenti attivi è migrata, e puoi forzare un reset per
gli account dormienti.
Qual è il numero giusto di thread per Argon2id?
OWASP raccomanda p=1 di default. Aumentare p non porta nulla se
il tuo server web tratta già molte richieste in parallelo, e complica il tuning.
Privilegia piuttosto l'aumento di m (memoria) che è la leva principale di
resistenza GPU.
Cos'è un «bcrypt decrypter»?
Non esiste un decrittatore bcrypt: la funzione è a senso unico per costruzione. Gli strumenti che pretendono di «decrittare» bcrypt non fanno altro che testare dizionari di password comuni contro l'hash. È esattamente la stessa cosa di un attaccante che avesse la tua tabella.
Argon2i o Argon2id?
Argon2id in tutti i casi per le password. Argon2i è leggermente più sicuro rispetto ai side-channel ma più debole rispetto agli attacchi GPU. Argon2id combina i vantaggi di entrambi ed è esplicitamente raccomandato dalla RFC 9106 per l'hashing di password.
Bisogna pepare (pepper) oltre al sale?
Il sale è sufficiente per la grande maggioranza delle applicazioni. Un pepe (chiave segreta memorizzata fuori dal database e utilizzata come HMAC prima dell'hash) aggiunge uno strato in caso di fuga della base senza compromissione del server applicativo. Argon2id non lo fornisce nativamente, va composto manualmente.