Se il tuo protocollo di autenticazione riguarda l'invio al server di una password, o un hash della password, con un semplice HTTP, allora questo è intrinsecamente molto debole, per due ragioni:
-
Qualcuno spiando la linea può registrare ciò che il client invia. Se l'invio di questi byte consente l'accesso, l'utente malintenzionato potrebbe semplicemente inviarli di nuovo. È un attacco di replay . Questo problema è ciò che allude @AviD nella sua risposta. Nessuna quantità di hashing lo risolverà. Alcuni protocolli tentano di correggere questo problema includendo una "sfida" dal server (un valore casuale, creato di nuovo per ciascuna connessione), da sottoporre a hash con la password sul client; questo è ciò che Autenticazione HTTP Digest riguarda.
-
Anche se l'autenticazione ha funzionato, questo è ancora un semplice HTTP, quindi qualunque dato verrà inviato in seguito sarà vulnerabile alle intercettazioni e alterazioni da parte di aggressori. Se il mezzo di trasporto non è protetto, l'autenticazione scoraggerà solo gli hacker più sofisticati. Qui è dove HTTP Digest fallisce.
Pertanto hai veramente bisogno di SSL (noto anche come HTTPS), non solo per comunicare la password o l'hash, ma anche il resto della conversazione tra client e server.
In futuro suppongo che il protocollo sia eseguito all'interno di un tunnel SSL. Hai ragione a voler usare un hash lento come bcrypt o PBKDF2; si noti che è necessario anche un sale per impedire la condivisione dei costi (ad esempio tabelle precompilate). L'hashing lento e salato viene utilizzato per far fronte alla debolezza intrinseca delle password. Ora, potresti voler scaricare parte dello sforzo di hashing sul client. Questo potrebbe funzionare, ma solleva alcuni problemi pratici:
-
Poiché l'elaborazione della password deve includere un salt, uno nuovo per ogni istanza di password, quindi il sale deve essere trasferito al client, in modo che il client possa includerlo nel processo di hashing che esegue. Ciò aumenta la complessità del protocollo: il client deve prima inviare il nome utente al server, quindi il server deve restituire il sale e (solo in quel momento) il client può iniziare a cancellare la password. Questo è un altro roundtrip della rete rispetto al solito "invia nome utente e password come una richiesta POST".
-
L'hashing lento consiste nell'accettare di spendere molta CPU su ciascuna password, in modo che l'attaccante anche debba spendere molto CPU su ciascuna password. Ma se la CPU spesa è sul client, non possiamo aumentarla quanto vorremmo, perché: 1) ci sono clienti che hanno pochissima CPU (ad esempio alcuni smartphone o tablet economici) e 2) il contesto Web implica usando Javascript, e le prestazioni di Javascript sono davvero pessime quando si parla di hashing (diciamo almeno 20 volte più lento del codice C).
Pertanto, la solita saggezza è che la parte dell'hash della password sul client non vale la pena.