Questo è principalmente un esperimento mentale per la comunicazione client / server, e voglio conoscere i difetti.
Quando viene creato un account utente (con U
come username e P
come password,) Genero un salt casuale ( S
) e memorizzo questi valori nel database (sul lato server) : U
, S
e H
che è calcolato come H = hash(U+S+P)
.
Durante l'autenticazione di un utente:
- Il client prima "tenta un'autenticazione" inviando
U
al server. - Il server crea un codice di sfida (
R
) per quell'utente e lo memorizza nel database, insieme al tempo in cui questa sfida scadrà (T
) e inviaR
eS
al client . - Il client calcola la propria versione di
H
(per hashingU
eS
eP
insieme, haU
eP
e ha ricevutoS
dal server.) - Il client calcola quindi un nuovo valore
G
comeG = hash(H+R)
e invia questoG
al server ("richiesta di autenticazione" effettiva). - Il server ha hash il proprio
H
insieme aR
per ricostruireG
e autentica l'utente se il suoG
corrisponde al valore ricevuto dal client eT
non è passato ancora. - Se l'autenticazione ha esito positivo o negativo,
R
viene rimosso dal database del server.
I difetti di cui sono già a conoscenza sono questi:
- Quando si crea un account, la password viene trasmessa in chiaro. Questo può essere mitigato utilizzando un servizio di creazione di account dedicato che utilizza SSL per la creazione di account.
- Se si tenta di eseguire l'autenticazione, alcune risorse verranno allocate sul server. Questo può essere mitigato consentendo solo un (o un numero fisso) di codici challenge per utente.
- Cercando di scoprire nomi utente e sali validi generando molti tentativi di autenticazione; che il server può sventare inviando un codice salt salt e challenge anche se l'utente non esiste.
Ecco le mie domande specifiche:
- Cosa mi manca? Dov'è il disastro in attesa di accadere?!
- Che cosa posso fare per rendere questo più sicuro / migliore? Oltre all'utilizzo di SSL e all'invio di password in chiaro (solo testo in chiaro dalla prospettiva della mia applicazione).
- Sto pensando a SHA-256 per tutti gli hash. Ci sono difetti nella famiglia SHA-2? Ishing i valori una volta sufficiente per generare
H
eG
? - Per generare
H
eG
, le altre permutazioni dei valori sono migliori? per esempio.P+U+S
,R+H
, ecc. - Quali comodità sto negando ai miei utenti? (A parte le loro autenticazioni che ora richiedono due round trip sul server.)
UPDATE : In definitiva, voglio fare questo:
Dopo una corretta autenticazione, il server genera una chiave di sessione K
come: K = hash(H+F)
dove F
è una stringa casuale. F
viene inviato all'utente e K
viene mantenuto nel database. Il client ricostruisce K
utilizzando il F
ricevuto e crittografa tutte le comunicazioni con il server d'ora in poi con un codice simmetrico (ad es. AES) con K
come chiave.