# Genera e verifica hash password bcrypt e Argon2id, nel browser

> Genera e verifica hash di password bcrypt ($2y$) e Argon2id nel browser: cost factor regolabile, salt automatico, niente upload. Perché non usare MD5 o SHA per le password.

Strumento gratuito nel browser (nessun upload): https://www.mauriziofonte.it/strumenti/bcrypt-argon2-generatore-hash

Due funzioni in un solo strumento. **Genera** l'hash di una password con **bcrypt** (formato `$2y$`) o **Argon2id** (formato `$argon2id$`), scegliendo il **cost factor** e i parametri memory-hard; oppure **verifica** se una password corrisponde a un hash esistente. Il **salt è generato automaticamente** a ogni calcolo e il tutto avviene **interamente nel browser**: la password non viene mai inviata a un server. Pensato per chi implementa autenticazione in PHP, Laravel, Symfony o WordPress e vuole capire davvero cosa produce `password_hash()` prima di metterlo in produzione.

## Come si usa

1. **Scegli algoritmo e parametri** - Seleziona **bcrypt** per la massima compatibilità o **Argon2id** per l'algoritmo memory-hard raccomandato oggi. Per bcrypt imposta il *cost factor* (default 12); per Argon2id imposta memoria, iterazioni e parallelismo. I default proposti seguono le raccomandazioni OWASP 2026.
2. **Genera l'hash** - Digita la password e premi **Genera hash**. Il salt casuale viene creato automaticamente e incorporato nell'output. Lo stesso testo genera un hash diverso a ogni click, ed è corretto così: il salt cambia ogni volta. Puoi incollarlo così com'è in un campo `password` del tuo database.
3. **Verifica una corrispondenza** - Nella seconda scheda incolla un hash esistente e la password in chiaro: il tool ricalcola usando il salt e i parametri letti dall'hash e ti dice se combaciano. Lato server lo stesso lavoro lo fa `password_verify()`; qui puoi provarlo senza scrivere codice.
4. **Porta il risultato in produzione** - Copia l'hash e confrontalo con quello che genera il tuo backend: devono avere lo stesso prefisso e la stessa struttura. In produzione non copiare hash a mano: usa `password_hash()` / `password_verify()` in PHP, `Hash::make()` in Laravel, la libreria nativa del tuo framework. Questo strumento serve a capire, testare e fare debug, non a sostituire il codice di autenticazione.

## Perché bcrypt o Argon2 e non MD5 o SHA

**La password non lascia il browser.** Hashare una password su un servizio online generico è un controsenso di sicurezza: stai inviando una credenziale in chiaro a un terzo. Qui il calcolo avviene interamente nel tab, in JavaScript e WebAssembly, senza alcuna richiesta di rete. Puoi verificarlo aprendo il pannello Network degli strumenti per sviluppatori: digiti una password, generi l'hash, e non parte nessuna richiesta HTTP. Una volta caricata, la pagina funziona anche offline.

**Le password non vanno hashate con funzioni veloci.** MD5, SHA-1, SHA-256 sono progettate per essere velocissime: una GPU moderna ne calcola miliardi al secondo. Applicata a una password, questa velocità lavora *a favore* dell'attaccante che ha rubato il database: con un dizionario e una scheda grafica prova miliardi di candidati al secondo. In più, senza salt, hash uguali rivelano password uguali e permettono l'uso di **rainbow table** precalcolate. bcrypt e Argon2 fanno l'opposto: sono **deliberatamente lente** e regolabili, così che ogni tentativo costi tempo (e per Argon2 anche memoria) all'attaccante.

**Il salt è già dentro l'hash.** Un hash bcrypt come `$2y$12$R9h/cIPz0gi.URNNX3kh2O...` è un pacchetto autoconsistente: `$2y$` è la versione, `12` è il cost factor, i 22 caratteri successivi sono il salt (128 bit casuali) e il resto è il digest vero e proprio (184 bit). Per Argon2id l'output `$argon2id$v=19$m=19456,t=2,p=1$salt$hash` incorpora versione, parametri di memoria/tempo/parallelismo, salt e digest. Non devi memorizzare il salt in una colonna separata: verificare significa rileggere quei parametri dall'hash e ricalcolare. È il motivo per cui `password_verify()` vuole solo password e hash, e nient'altro.

**bcrypt o Argon2id: quale.** Per un nuovo progetto la raccomandazione 2026 è **Argon2id**, che è *memory-hard*: costringe l'attaccante a usare molta RAM per ogni tentativo, neutralizzando il vantaggio di GPU e ASIC che invece macinano bene bcrypt. bcrypt resta perfettamente valido, è ovunque (PHP, Laravel, Spring, Node) e non ha dipendenze particolari: il suo limite storico è che tronca la password a 72 byte e non è memory-hard. Se il tuo stack supporta Argon2id, preferiscilo; se devi restare compatibile con un ecosistema che parla bcrypt, un cost factor adeguato è ancora una scelta solida.

## Glossario

- **bcrypt**: Funzione di hashing delle password basata sul cifrario Blowfish, presentata da Niels Provos e David Mazières nel 1999. Deliberatamente lenta e con cost factor regolabile. L'output di 60 caratteri incorpora versione, costo e salt. Limite noto: tronca la password oltre i 72 byte. Prefissi comuni: `$2a$`, `$2b$`, `$2y$` (la variante di PHP).
- **Argon2**: Vincitrice della Password Hashing Competition (2015) e standard RFC 9106. Tre varianti: Argon2d (resistente a GPU), Argon2i (resistente ad attacchi side-channel), **Argon2id** (ibrida, quella da usare). È memory-hard: i parametri sono memoria, iterazioni (tempo) e parallelismo. È la raccomandazione di default per i nuovi sistemi.
- **Salt**: Valore casuale, univoco per ogni password, mescolato all'input prima dell'hashing. Rende diverso l'hash di due password identiche e vanifica le rainbow table precalcolate. In bcrypt e Argon2 il salt è generato automaticamente e incorporato nell'hash: non va conservato a parte.
- **Cost factor**: In bcrypt, il parametro (tipicamente 10-14) che fissa il numero di iterazioni interne come 2^cost. Ogni incremento di 1 raddoppia il tempo di calcolo. Serve a mantenere l'hashing abbastanza lento da scoraggiare il brute force, ma abbastanza veloce da non degradare il login.
- **Work factor**: Termine generico per il parametro che rende costosa una funzione di hashing password: il cost di bcrypt, oppure la terna memoria/iterazioni/parallelismo di Argon2 e scrypt. Va calibrato sull'hardware di produzione e alzato nel tempo, man mano che le CPU diventano più veloci.
- **Memory-hard**: Proprietà di una funzione (Argon2, scrypt) che richiede molta memoria RAM per essere calcolata, oltre al tempo. Toglie all'attaccante il vantaggio di GPU e ASIC, hardware potentissimo nel calcolo ma limitato nella memoria per singolo core. bcrypt è privo di questa proprietà, e qui sta la differenza principale con Argon2id.
- **Rainbow table**: Tabella precalcolata che associa hash a testi in chiaro, per invertire in fretta hash senza salt. Il salt univoco per password la rende inutile: l'attaccante dovrebbe precalcolare una tabella per ogni salt possibile. È uno dei motivi per cui MD5/SHA senza salt sono inadatti alle password.
- **password_hash()**: Funzione nativa di PHP (dal 5.5) per generare hash di password sicuri. Accetta l'algoritmo (`PASSWORD_BCRYPT`, `PASSWORD_ARGON2ID`) e le opzioni di costo, genera un salt sicuro e restituisce una stringa autoconsistente. Va usata insieme a `password_verify()` e `password_needs_rehash()`.
- **phpass**: Portable PHP password hashing framework di Solar Designer, usato storicamente da WordPress, Drupal e phpBB. Nella modalità portabile applica key stretching su MD5 (prefisso `$P$`): meglio di un MD5 nudo, ma superato da bcrypt e Argon2. WordPress è passato a bcrypt dalla versione 6.8.

## Domande frequenti

### Le password che inserisco restano nel browser?

Sì, e puoi verificarlo. Apri gli strumenti per sviluppatori (F12), vai sul pannello Network e inizia a registrare: genera o verifica un hash e non vedrai partire nessuna richiesta HTTP. Il calcolo di bcrypt e Argon2 gira in JavaScript e WebAssembly dentro il tab. Nessuna password, nessun hash e nessun parametro lasciano il tuo computer. Dopo il caricamento la pagina funziona anche offline.

### Perché non posso usare MD5 o SHA-256 per le password?

Perché sono troppo veloci e non pensati per questo scopo. Una GPU moderna calcola miliardi di hash MD5 o SHA al secondo: applicata a un database rubato, questa velocità permette all'attaccante di provare enormi dizionari di password in poco tempo. In più, senza salt, due utenti con la stessa password producono lo stesso hash e diventano vulnerabili alle rainbow table. bcrypt e Argon2 sono progettate all'opposto: lente, regolabili e con salt automatico.

### Cosa è il cost factor e come lo scelgo?

In bcrypt il cost factor è l'esponente che determina il numero di iterazioni: 2^cost. Un cost di 12 significa 4096 iterazioni; passare a 13 raddoppia il tempo. L'idea è tenere l'hashing lento per l'attaccante ma tollerabile al login (indicativamente 200-500 ms sull'hardware di produzione). Nel 2026 un buon punto di partenza per bcrypt è 12, con minimo 10 secondo OWASP. Misura sul tuo server e alza il valore nel tempo.

### Meglio bcrypt o Argon2id?

Per un nuovo progetto, Argon2id: è memory-hard, quindi costringe l'attaccante a spendere anche RAM per ogni tentativo e neutralizza il vantaggio delle GPU. bcrypt resta valido, universale e semplice da integrare, ma non è memory-hard e tronca la password a 72 byte. In pratica: se il tuo stack supporta Argon2id, usalo; se devi restare compatibile con un ecosistema bcrypt, un cost factor adeguato è ancora una scelta solida e diffusissima.

### Cosa è il salt e devo conservarlo separatamente?

Il salt è un valore casuale unico per ogni password, che rende diverso l'hash anche di password identiche e vanifica le rainbow table. Con bcrypt e Argon2 NON devi conservarlo a parte: è già incorporato nell'hash. Nell'output bcrypt sono i 22 caratteri dopo il cost factor; in Argon2id è il segmento tra i parametri e il digest. La verifica lo rilegge da lì automaticamente.

### L'hash è reversibile? Posso risalire alla password?

No. bcrypt e Argon2 sono funzioni a senso unico: dall'hash non si torna alla password. Verificare non significa decifrare, ma ricalcolare l'hash della password candidata usando salt e parametri letti dall'hash memorizzato, e confrontare i due digest. Lo fanno sia questo tool nella scheda di verifica sia `password_verify()` lato server.

### Posso incollare qui un hash di produzione per verificarlo?

Su questo strumento sì, perché il calcolo è interamente client-side e offline: nessun dato esce dal browser. In generale, però, non incollare mai coppie password+hash di produzione su servizi online di cui non controlli il codice: staresti inviando credenziali reali a terzi. La regola sicura è verificare solo su strumenti locali o su ambienti che sai essere client-side, come questo.

### Perché lo stesso testo genera un hash diverso ogni volta?

Perché il salt è casuale e viene rigenerato a ogni calcolo. È il comportamento corretto e voluto: due hash diversi della stessa password restano entrambi verificabili, perché ciascuno porta con sé il proprio salt. Se ti aspettavi un output deterministico stavi pensando a un hash tipo SHA, che per le password è proprio ciò che va evitato.

### Quale cost o quali parametri dovrei usare in produzione?

Per bcrypt: cost 12 come default 2026, minimo 10, calibrato per stare sotto i 500 ms sul tuo hardware. Per Argon2id il minimo OWASP è 19 MiB di memoria, 2 iterazioni e parallelismo 1; se il server ha RAM e CPU, puoi salire (ad esempio 46-64 MiB). L'importante è misurare sulla macchina reale di produzione, non su questo browser, e rivedere i parametri periodicamente.

### Come integro bcrypt o Argon2 nel mio codice?

Non reimplementare l'algoritmo: usa la libreria nativa. In PHP `password_hash()` e `password_verify()`; in Laravel `Hash::make()` e `Hash::check()`; in Symfony il componente PasswordHasher; in Node librerie come bcrypt o argon2. Al login controlla `password_needs_rehash()` (o l'equivalente) per aggiornare gradualmente il cost factor senza costringere gli utenti a cambiare password.

---
Uno strumento di Maurizio Fonte, senior backend engineer. Tutti gli strumenti: https://www.mauriziofonte.it/strumenti/
