Is this a secure way to hash passwords?
Probabilmente, ma molta della tua complessità aggiuntiva non aggiunge davvero molto valore di sicurezza.
L'idea di un sale è quella di garantire che non vi sia alcun metodo più efficiente per recuperare le password piuttosto che forzare ogni singolo di esse da zero. Quindi il tuo obiettivo è di garantire che due account non abbiano lo stesso sale (ad esempio è globalmente unico). Se lo facessero, un utente malintenzionato potrebbe sostanzialmente ottenerne due al prezzo di uno costruendo una tabella di ricerca mentre il bruto forzerà il primo.
Per raggiungere questo obiettivo hai bisogno di abbastanza entropia nel sale per garantire che la probabilità che due account abbiano lo stesso sale sia trascurabile.
Randomly generated salt (using a function designed for generating password salts). This is stored in the MySQL database.
Questa è la fonte primaria di entropia nel tuo schema. Probabilmente potresti scartare il resto senza compromettere in modo significativo la sicurezza.
Tuttavia, affinché questo sale sia efficace, devi assicurarti di:
- Il valore casuale che stai utilizzando viene generato utilizzando un RNG adatto per applicazioni crittografiche.
- Ci sono abbastanza bit nel tuo valore casuale per minimizzare la probabilità di una collisione salina. OWASP suggerisce almeno 32 bit.
Static salt - hard-coded into the source-code.
Questo sta aggiungendo un valore crittografico minimo. Da un punto di vista teorico non aggiunge alcuna entropia aggiuntiva presumendo che l'hacker conosca il valore, e dal punto di vista pratico i server DB sono generalmente compromessi tramite le credenziali ottenute da un'applicazione compromessa.
I'm using sha512, by the way.
Anche se si tratta di un algoritmo di hashing crittograficamente sicuro, è anche un processo "veloce", che rappresenta un problema dato che gli utenti utilizzano in genere password deboli. Dovresti prendere in considerazione l'utilizzo di un algoritmo di hashing lento (ad esempio bcrypt) o iterare il tuo processo di hashing di 10k circa volte. Se ci vuole circa un secondo per calcolare ogni hash, anche un attacco di dizionario impiegherà molto tempo.
When checking the hash, I generate 100 different hashes with the static salt, the salt stored in the database, and one of the possible random numbers, if one of them matches the password is correct.
Il valore di questo è minimo, in pratica stai semplicemente aggiungendo uno o due caratteri extra alla password e poi bruto forzandoli ogni volta. Questo rallenterà il tuo schema di hashing che è buono, ma starai meglio usando la tecnica sopra per ottenere questo.