Idealmente , dovremmo fare la maggior parte (ma non tutti!) dell'hashing sul lato client.
Il bisogno generale di hashing della password, con tutte le iterazioni e i sali coinvolti (vedi questa risposta ), è quello di assicurarsi che il valore archiviato (il" token di verifica password ") non possa essere facilmente utilizzato per un attacco di dizionario offline (l'utente malintenzionato tenta la password potenziale, fino a uno che corrisponde al il valore memorizzato è stato trovato). Affinché quella funzionalità specifica sia soddisfatta, è sufficiente che l'hashing della password lenta e salata si verifichi "da qualche parte" e che la macchina client sia un posto ragionevole.
Tuttavia, la protezione dagli attacchi di dizionario offline è solo una parte dell'obiettivo di sicurezza. In particolare, non vogliamo che un utente malintenzionato sia in grado di ottenere valori "equivalenti alla password". Se esegui l'hashing completo lato client, e memorizzi il valore "così com'è" sul server, allora un'anteprima sul database del server (come accade troppo spesso con iniezioni SQL e nastri di backup persi) rivelerà i valori hash e consentirà l'attaccante per accedere immediatamente come qualsiasi utente. Pertanto, vuoi comunque eseguire alcuni hashing lato server.
Ciò che funziona, ad esempio, è avere l'hash lento e salato sul client, risultante in un valore V e il server memorizza SHA-256 ( V ). Dato che l'hash lento e salato è stato fatto, la protezione contro gli attacchi di dizionario è lì; e poiché il server non memorizza V ma richiede ancora al client di inviare V per ottenere l'accesso, le violazioni di sola lettura non vengono ridimensionate banalmente in un compromesso completo in lettura-scrittura.
L'hashing lato client ha la caratteristica molto interessante dell'utilizzo delle risorse lato client, non lato server, consentendo così a un determinato server di elaborare molti client concorrenti senza esaurire la CPU, pur avendo ancora un hashing di password lento e salato complessivo. Tuttavia, questo non è spesso fatto in pratica a causa di alcuni inconvenienti:
-
Il client non può eseguire l'hash senza conoscere il sale, che è memorizzato sul server. Il protocollo implica quindi un ulteriore viaggio di andata e ritorno: il client deve inviare il nome utente, il server risponde con il sale, e quindi (solo allora) il client può eseguire l'hash lento e salato.
-
I client sono eterogenei: alcuni possono essere piuttosto deboli, il che implica un limite rigido al numero di iterazioni che possono essere applicate (perché uno smartphone lento come client non significa che l'utente umano è più paziente). Questo è particolarmente vero per i client basati sul Web, perché i calcoli Javascript sono terribilmente lenti (se confrontati con il codice nativo o persino con le applet Java o Silverlight).
-
Hash lato client indica codice lato client, che potrebbe non essere facilmente aggiornato o modificato. Con l'hashing sul lato server, la scelta della funzione hash dipende interamente dal server e può essere cambiata senza dover modificare in alcun modo i client installati.
-
Alcuni server preferiscono avere accesso a password non crittografate di tanto in tanto, non per l'archiviazione, ma per altre funzionalità come la rilevazione automatica di password utente molto povere o l'invio di una copia delle password alle autorità competenti (ove applicabile) - Non sto dicendo che questo è buono o cattivo , ma quando si applica, non è soggetto alla scelta di chi progetta il sistema di accesso; un paese in cui deve consentire alle agenzie governative di dare un'occhiata alle password, quindi, beh, è necessario, quindi diventa un elemento del contesto da trattare).