Stavo cercando di progettare un sistema di autenticazione che renderebbe molto più difficile indovinare una password tramite la forza bruta e ridurre il rischio per un utente se la password con hash è stata rubata tramite un attacco basato sullo snooping. Inoltre, dal momento che il mio codice client può essere facilmente visualizzato da coloro che desiderano vederlo (è in un linguaggio interpretato, tuttavia, crittografo e offusisco il client distribuito), volevo essere in grado di impedire a un utente malintenzionato di guardare la fonte per impersonare facilmente un utente. La sicurezza attraverso l'oscurità è NON sicurezza.
Ecco l'algoritmo che ho ideato. Volevo sottoporlo a un esame pubblico perché gli algoritmi di crittografia funzionano sempre meglio se sottoposti a più opinioni possibili, IMHO.
(Tutti gli hash sono calcolati con SHA-2 e una dimensione di blocco di 512 bit. Questo algoritmo non è vulnerabile a eventuali collisioni o attacchi pre-immagine ed è una funzione di hash crittografica sicura.)
[CLIENT LATO]
-
L'utente fornisce un nome utente di qualsiasi carattere / simbolo / numero inferiore a 30 caratteri e una password di qualsiasi carattere / simbolo / numero compresa tra 8 e 200 caratteri.
-
Il nome utente è hash.
-
L'hash del nome utente viene aggiunto alla fine della password dell'utente come salt.
-
La password salata viene sottoposta a hash e quindi hash hash.
-
La data e l'ora correnti vengono richieste dal server di autenticazione e vengono quindi sottoposte a hash.
-
L'hash del timestamp viene aggiunto all'hash username / password come quello che chiamerò "sale dipendente dal tempo". Quest'ultima combinazione viene quindi sottoposta a hash per produrre l'hash di autenticazione finale.
-
Il nome utente, l'hash con data e ora, la password salata e il tempo impiegato per generare il sale dipendente dal tempo vengono inviati al server tramite una connessione TLS / SSL.
[SERVER SIDE]
-
Il server verifica che il timestamp ricevuto sia nell'ultimo minuto. Se non lo è, il server indicherà che l'autenticazione è fallita.
-
Il server ha il nome utente / password salata e lo confronta con l'hash salato / password del database memorizzato. Se non corrispondono l'autenticazione fallisce. (Per chiarire, il server ha un hash hash della password salata che verifica contro un hash dell'hash della password salato dato dal client.)
-
Il server calcola un hash del timestamp inviato dal client.
-
Il server annulla l'hash del timestamp generato e l'hash della password salata per formare l'hash di autenticazione.
-
Confronta l'hash di autenticazione prodotto con l'hash di autenticazione inviato dal client. Se sono uguali, segnala l'autenticazione. Altrimenti segnala un errore di autenticazione.
Se sono corretto, credo che questo schema di autenticazione faccia davvero impazzire una password bruta e rende la password rubata tramite lo snooping utile solo per un minuto intero.
Tuttavia, ciò a cui non protegge, come penso sia impossibile, è il furto di password da parte dell'utente quando vengono inserite nel client. Lo spyware sarebbe in grado di rubare il nome utente e la password effettivi.
EDIT 1 :: Risolto il problema con il processo di autenticazione in modo che il server non memorizzasse l'hash della password salata, solo un hash di quel valore. Ciò impedisce a un utente malintenzionato con accesso al database di conoscere la password originale. Il motivo per cui questo deve essere fatto è il valore hash della password salata. Hash è la password dal punto di vista del server. Memorizzare l'hash della password salata nel database equivale a memorizzare tutte le password dell'utente in testo semplice.
EDIT 2 : risolto lo schema in modo che l'autenticazione si basasse sull'ora del server, non sul client.
EDIT 3 :: Ha reso la lunghezza della password meno restrittiva, ma l'ha mantenuta ragionevole.