Per comprendere questo problema, devi prima capire perché abbiamo le password hash. È completamente possibile memorizzare una password in chiaro su un server e confrontare semplicemente la password trasmessa alla password ricevuta. Finché la password è protetta durante il transito, questo è un mezzo di autenticazione sicuro (segreto condiviso).
Il motivo per cui le password sono hash è perché il problema non è l'autenticazione, ma l'archiviazione. Se il server viene mai compromesso, l'utente malintenzionato ha immediatamente accesso a tutti gli account utente poiché ora conoscono il segreto utilizzato per l'autenticazione degli utenti.
L'hashing funge da barriera a questo. Poiché il server non conosce l'effettivo input richiesto per l'autenticazione, anche un compromesso al DB non garantisce a un utente malintenzionato l'accesso agli account utente. Avrebbero ancora bisogno di capire l'input da dare per raggiungere i valori hash a cui l'applicazione fa riferimento. Certo, potrebbero modificare tutti i valori in qualcosa che sanno, ma questo potrebbe sollevare rapidamente sospetti e il sistema dovrebbe essere chiuso e protetto.
Quindi, il problema con l'hashing del lato client è che rende effettivamente il risultato dell'hash la password piuttosto che la password. Non c'è nulla che impedisca a un utente malintenzionato di aggirare il client ufficiale e semplicemente di inviare direttamente l'hash finito al server. Non fornisce alcuna ulteriore (o perdita) di sicurezza durante l'autenticazione, ma nella situazione in cui l'hashing è progettato per la protezione, non offre nulla poiché l'hash memorizzato nel DB è in realtà il segreto condiviso trasmesso al server.
Detto questo, ci sono due cose notevoli che l'hashing lato client ti dà. Anche se non aiuta a proteggere il tuo sistema, può aiutare a proteggere il tuo utente. Se si trasmette la password in modo non sicuro o la trasmissione viene compromessa senza che il codice client venga compromesso, si continuerà a proteggere la password dell'utente (che potrebbero essere riutilizzati su altri siti) da eventuali perdite.
L'altro è che è possibile fornire iterazioni aggiuntive di un hash per rendere più difficile un attacco offline contro il DB senza dover utilizzare cicli del server (mentre si estende anche la lunghezza della "password intermedia che il client invia"), ma hai ancora bisogno di cicli di server sufficienti per proteggere la password estesa contro un client canaglia. Anche in questo caso, la protezione primaria che offre impedisce la scoperta della password originale, ma non aiuta a proteggere il meccanismo di autenticazione del tuo sito.
In altre parole, mentre fornisce alcune protezioni minori, dal punto di vista del server, l'hash del lato client dovrebbe essere trattato come se fosse la password diretta dell'utente. Non fornisce né più né meno sicurezza sul server se l'utente avesse fornito direttamente la propria password e dovesse essere protetto come tale.
Se vuoi essere in grado di fornire quel livello extra di sicurezza, consiglierei due hash. Hash una volta lato client per creare una nuova password univoca, quindi eseguire l'hashing della password sul server per creare un valore memorizzato nel DB. In questo modo ottieni il meglio da entrambi i mondi.
Per la maggior parte, SSL è sufficientemente affidabile per proteggere lo scambio che l'hash iniziale prima della trasmissione è visto come non necessario e un server compromesso potrebbe sempre alterare il codice inviato al client in modo tale che l'hash iniziale non venga eseguito . Semplicemente non è un'alternativa efficace a SSL e non offre un vantaggio aggiuntivo sufficiente a valerne i costi e la complessità.