DISCLAIMER : questa risposta è stata scritta nel 2008.
Da allora, PHP ci ha dato password_hash
e password_verify
e, fin dalla loro introduzione, sono la raccomandata hashing delle password e metodo di controllo.
La teoria della risposta è comunque una buona lettura.
TL; DR
cosa non fare
- Non limitare i caratteri che gli utenti possono inserire per le password. Solo gli idioti lo fanno.
- Non limitare la lunghezza di una password. Se i tuoi utenti desiderano una frase con supercalifragilisticexpialidocious, non impedire loro di usarla.
- Non rimuovere o sfuggire a HTML e caratteri speciali nella password.
- Non archiviare mai la password dell'utente in testo semplice.
- Non inviare mai una password via e-mail al tuo utente, tranne quando ha perso la sua e ne hai inviata una temporanea.
- Mai e poi mai registrare le password in alcun modo.
- Non inserire mai le password con SHA1 o MD5 o SHA256! I cracker moderni possono superare 60 e 180 miliardi di hash / secondo (rispettivamente).
- Non mescolare bcrypt e con la cruda uscita di hash () , sia in uscita uso esadecimale o base64_encode esso. (Questo vale per qualsiasi input che può avere una canaglia
\0
, che può indebolire seriamente la sicurezza.)
dos
- Usa scrypt quando puoi; bcrypt se non puoi.
- Utilizzare PBKDF2 se non è possibile utilizzare bcrypt o scrypt, con hash SHA2.
- Ripristina le password di tutti quando il database è compromesso.
- Implementa una lunghezza minima ragionevole di 8-10 caratteri, oltre a richiedere almeno 1 lettera maiuscola, 1 lettera minuscola, un numero e un simbolo. Ciò migliorerà l'entropia della password, a sua volta rendendola più difficile da decifrare. (Vedi la sezione "Cosa rende una buona password?" Per alcuni dibattiti.)
Perché comunque le password hash?
L'obiettivo dietro le password di hashing è semplice: impedire l'accesso dannoso agli account utente compromettendo il database. Quindi l'obiettivo dell'hash delle password è quello di scoraggiare un hacker o un cracker costando loro troppo tempo o denaro per calcolare le password in chiaro. E i tempi / i costi sono i migliori deterrenti nel tuo arsenale.
Un altro motivo per cui si desidera un hash valido e affidabile su un account utente è darti il tempo sufficiente per cambiare tutte le password nel sistema. Se il tuo database è compromesso, avrai bisogno di tempo sufficiente per bloccare almeno il sistema, altrimenti cambia tutte le password nel database.
Jeremiah Grossman, CTO di Whitehat Security, ha dichiarato sul blog di White Hat Security dopo un recente recupero della password che ha richiesto la rottura della forza di protezione della sua password:
È interessante notare che, vivendo questo incubo, ho imparato MOLTO che non sapevo su cracking, archiviazione e complessità delle password. Ho imparato perché l'archiviazione delle password è molto più importante della complessità delle password. Se non sai come è memorizzata la tua password, tutto ciò di cui puoi veramente fare affidamento è la complessità. Questa potrebbe essere una conoscenza comune di password e professionisti della crittografia, ma per l'esperto medio di InfoSec o Web Security, ne dubito fortemente.
(Enfasi mia.)
Cosa rende comunque una buona password?
Entropia . (Non che sottoscrivo pienamente il punto di vista di Randall.)
In breve, l'entropia è la quantità di variazione all'interno della password. Quando una password è solo lettere latine minuscole, sono solo 26 caratteri. Questa non è molta variazione. Le password alfanumeriche sono migliori, con 36 caratteri. Ma consentire maiuscole e minuscole, con simboli, è di circa 96 caratteri. È molto meglio delle semplici lettere. Un problema è che per rendere memorabili le nostre password inseriamo dei pattern, che riducono l'entropia. Oops!
L'entropia della password si approssima facilmente. L'uso dell'intera gamma di caratteri ascii (circa 96 caratteri tipizzabili) produce un'entropia di 6,6 per carattere, che a 8 caratteri per una password è ancora troppo bassa (52.679 bit di entropia) per la sicurezza futura. Ma la buona notizia è: password più lunghe e password con caratteri unicode aumentano davvero l'entropia di una password e rendono più difficile decifrare.
C'è una discussione più lunga sull'entropia delle password sul sito Crypto StackExchange . Una buona ricerca su Google produrrà anche molti risultati.
Nei commenti ho parlato con @popnoodles, che ha sottolineato che l' applicazione di una politica di password di lunghezza X con molte lettere, numeri, simboli, ecc. X può effettivamente ridurre l'entropia rendendo lo schema delle password più prevedibile. Sono daccordo. La casualità, il più casuale possibile, è sempre la soluzione più sicura ma meno memorabile.
Per quanto ne so, fare la migliore password del mondo è un Catch-22. O non è memorabile, troppo prevedibile, troppo breve, troppi caratteri unicode (difficili da digitare su un dispositivo Windows / Mobile), troppo lunghi, ecc. Nessuna password è davvero abbastanza buona per i nostri scopi, quindi dobbiamo proteggerli come se fossero erano a Fort Knox.
Migliori pratiche
Bcrypt e scrypt sono le migliori pratiche attuali. Scrypt sarà migliore di bcrypt nel tempo, ma non ha visto l'adozione come standard da Linux / Unix o dai server web e non ha ancora pubblicato recensioni approfondite del suo algoritmo. Tuttavia, il futuro dell'algoritmo sembra promettente. Se stai lavorando con Ruby c'è una gemma scrypt che ti aiuterà, e Node.js ora ha il suo pacchetto scrypt . Puoi usare Scrypt in PHP tramite l' estensione Scrypt o l' estensione Libsodium (entrambi sono disponibili in PECL).
Consiglio vivamente di leggere la documentazione per la funzione crypt se vuoi capire come usare bcrypt o trovarti un buon wrapper o usare qualcosa come PHPASS per un'implementazione più legacy. Raccomando un minimo di 12 round di bcrypt, se non da 15 a 18.
Ho cambiato idea sull'uso di bcrypt quando ho saputo che bcrypt utilizza solo il programma chiave di blowfish, con un meccanismo a costo variabile. Quest'ultimo consente di aumentare i costi per forzare la password di una password aumentando il programma di chiavi già costoso di Blowfish.
Pratiche medie
Quasi non riesco più a immaginare questa situazione. PHPASS supporta PHP da 3.0.18 a 5.3, quindi è utilizzabile su quasi tutte le installazioni immaginabili e dovrebbe essere usato se non si è certi che il proprio ambiente supporti bcrypt.
Supponiamo però che non sia possibile utilizzare bcrypt o PHPASS. Cosa poi?
Prova un'implementazione di PDKBF2 con il numero massimo di round che il tuo ambiente / applicazione / percezione dell'utente può tollerare. Il numero più basso che consiglierei è di 2500 colpi. Inoltre, assicurarsi di utilizzare hash_hmac () se è disponibile per rendere più difficile la riproduzione dell'operazione.
Pratiche future
In PHP 5.5 è disponibile una libreria completa di protezione con password che elimina qualsiasi problema di collaborazione con bcrypt. Mentre la maggior parte di noi è bloccata con PHP 5.2 e 5.3 negli ambienti più comuni, in particolare gli host condivisi, @ircmaxell ha creato un livello di compatibilità per l'API in arrivo che è retrocompatibile con PHP 5.3.7.
Riepilogo e dichiarazione di non responsabilità sulla crittografia
Non esiste la potenza di calcolo necessaria per decifrare una password con hash. L'unico modo per i computer di "decifrare" una password è ricrearla e simulare l'algoritmo di hashing utilizzato per proteggerla. La velocità dell'hash è linearmente correlata alla sua capacità di essere forzata brutalmente. Peggio ancora, la maggior parte degli algoritmi di hash può essere facilmente parallelizzata per funzionare ancora più velocemente. Ecco perché schemi costosi come bcrypt e scrypt sono così importanti.
Non puoi prevedere tutte le minacce o le vie di attacco, quindi devi fare del tuo meglio per proteggere gli utenti in anticipo . Se non lo fai, potresti anche perdere il fatto di essere stato attaccato fino a quando non è troppo tardi ... e sei responsabile . Per evitare quella situazione, agire paranoico per cominciare. Attacca il tuo software (internamente) e tenta di rubare le credenziali dell'utente, o modificare gli account di altri utenti o accedere ai loro dati. Se non collaudi la sicurezza del tuo sistema, non puoi incolpare nessuno tranne te stesso.
Infine: non sono un crittografo. Qualunque cosa abbia detto è la mia opinione, ma mi capita di pensare che sia basato sul buon vecchio senso comune ... e su molte letture. Ricorda, sii il più paranoico possibile, rendi le cose più difficili da intromettere il più possibile, quindi, se sei ancora preoccupato, contatta un hacker o un crittografo dal cappello bianco per vedere cosa dicono del tuo codice / sistema.