it-swarm.dev

Hashing della password lato client

Modifica: aggiornato per dare maggiore enfasi all'obiettivo: tranquillità per l'utente e non rafforzare la sicurezza.

Dopo aver letto alcune discussioni qui sull'hash delle password lato client, mi chiedo ancora se potrebbe essere corretto utilizzarlo in una situazione particolare.

In particolare vorrei avere il client - a Java - hash la loro password usando qualcosa come PBKDF2, usando come sale una combinazione del loro indirizzo e-mail e un pezzo costante di byte specifico per l'applicazione . L'idea è che l'hash è riproducibile per l'autenticazione, ma si spera non sia vulnerabile agli attacchi di reverse engineering (per scoprire la password letterale) diverso dalla forza bruta se il i dati del server sono compromessi.

Obiettivo:

L'hash lato client è per la tranquillità dell'utente che la sua password letterale non viene mai ricevuta dal server, anche se c'è comunque la sicurezza di averla in archivio. Un altro vantaggio collaterale (o forse una responsabilità?) È che il costo di hashing di un PBKDF2 iterato o simili è a carico del cliente.

Le caratteristiche dell'ambiente sono:

  1. Tutte le comunicazioni client-server sono crittografate.
  2. I messaggi riprodotti non sono consentiti. vale a dire. l'hash inviato dal client non può essere effettivamente utilizzato come password da un intercettatore.
  3. L'IP temporaneo e la blacklist sono possibili per più tentativi di accesso non riusciti in un breve lasso di tempo. Questo può essere per account utente o a livello di sistema.

Preoccupazioni:

  1. "Evitare di elaborare schemi di autenticazione fatti in casa."
  2. Il sale è deterministico per ogni utente, anche se gli hash prodotti saranno specifici per questa applicazione a causa dei (identici) byte extra gettati nel sale. È male?
  3. Le autenticazioni sul lato server verranno eseguite senza ritardi significativi, senza costi di hashing. Ciò aumenta la vulnerabilità agli attacchi di autenticazione a forza bruta distribuita?
  4. I clienti non autorizzati possono fornire un hash debole per i propri account. In realtà, non troppo preoccupato per questo.
  5. Il server dovrebbe ripassare gli hash del client prima di archiviarli?

Pensieri?

31
Foy Stip

L'hash sul lato client non risolve il problema principale che l'hash della password è destinato a risolvere: cosa succede se un utente malintenzionato ottiene l'accesso al database delle password con hash. Poiché le password (con hash) inviate dai client sono memorizzate così come sono nel database, un utente malintenzionato può impersonare tutti gli utenti inviando al server le password con hash dal database così come sono.

D'altra parte, l'hash sul lato client è bello in quanto assicura l'utente che il server non è a conoscenza della password - che è utile se l'utente utilizza la stessa password per più servizi (come la maggior parte degli utenti lo fa).

Una possibile soluzione è l'hashing sia sul lato client che sul lato server. È comunque possibile scaricare sul client l'operazione pesante PBKDF2 ed eseguire una singola operazione hash (sul lato client password hash PBKDF2) sul lato server. Il PBKDF2 nel client impedirà gli attacchi del dizionario e la singola operazione di hash sul lato server impedirà di utilizzare le password con hash da un database rubato così com'è.

45
David Wachtfogel

Ci sono pochi momenti in cui vale la pena hashing lato client. Una di queste circostanze è quando il processo di hash è intensivo dal punto di vista computazionale, il che può essere il caso di PBKDF2.

Affrontare le tue preoccupazioni:

  1. Evita anche suggerimenti non convalidati sulla crittografia che trovi su Internet. (Dichiarazione di non responsabilità: non sono Bruce Schneier.)
  2. I sali deterministici non sono un problema: l'unico vero requisito del sale è che è unico per ogni utente. Il vero scopo di Salt è impedire che una forza bruta su una password si trasformi in una forza bruta su tutte le password nel caso di un database compromesso. Anche se dovessi archiviare un salt casuale nel tuo database accanto alla password con hash, raggiungeresti comunque questo obiettivo, a condizione che ogni utente sia diverso.
  3. Come ho detto sopra, PBKDF2 è bello perché puoi decidere arbitrariamente la difficoltà computazionale dell'hash. È possibile selezionare un c tale che un singolo hash sull'hardware moderno impieghi pochi secondi, eliminando efficacemente il rischio di un attacco di forza bruta a livello di API. (Ovviamente, il tuo client potrebbe non avere un ritardo così lungo all'accesso.)
  4. Gli utenti possono scegliere password semplici: si stanno solo facendo del male. Se si desidera eliminare questo rischio, è necessario che il server generi l'hash la prima volta, a condizione che la password passi su un canale crittografato.
  5. Sì, e dovrai salare in modo univoco anche questi. In caso di compromissione del database, si desidera assicurarsi che l'attaccante non ottenga informazioni che gli consentano di autenticarsi direttamente come qualsiasi utente sul proprio sistema. Un avvertimento qui è che non vuoi che il tuo hashing lato server sia intensivo dal punto di vista computazionale come lo è il tuo hash lato client. Se l'hash lato server richiede troppi sforzi, ti apri a un vettore di attacco Denial of Service che esaurisce la CPU: un utente malintenzionato invia semplicemente tentativi di autenticazione di password vuote su Tor, password che il tuo server deve provare a eseguire l'hashing prima di sapere che lo sono fraudolento, lasciandoti alla fine con un server sopraffatto ...
12
Motoma

Se si esegue l'hashing della password sul lato client, qualunque sia il risultato è IS la password, quindi non si ottiene alcuna sicurezza reale. Qualsiasi hack o perdita di informazioni che avrebbe rivelato la password in chiaro rivelerà invece la password con hash, che è la vera password.

Ciò non deve essere confuso con schemi di autenticazione a conoscenza zero, in cui uno scambio di messaggi dimostra che il client conosce la vera password, senza effettivamente trasmetterla.

9
ddyer

Sembra che tu stia cercando di inventare il tuo protocollo crittografico. Dalla descrizione del tuo approccio, non sembra che tu abbia lo sfondo per farlo in modo sicuro. Consiglio vivamente di usare protocolli esistenti invece di crearne di vostri.

Innanzitutto, non è chiaro quale modello di minaccia pensi di aggirare. Citi qualcosa chiamato "attacco di ingegneria inversa" che non ha una vera definizione o significato.

In secondo luogo, la tua comprensione dello scopo di un sale e delle migliori pratiche per la sua generazione sembrano mancare. I sali non devono essere tenuti segreti. Puoi (e dovresti) generare un unico sale da un CSPRNG per ogni nuovo token di autenticazione e non da qualcosa come un indirizzo e-mail (che potrebbe cambiare). I sali specifici dell'applicazione specifici a volte sono chiamati "peperoni" e non sono a conoscenza di alcuna letteratura crittografica che supporti o incoraggi il loro uso.

Terzo, PBKDF2 va bene, ma seriamente solo sa BCrypt . BCrypt è stato progettato per questo ed è ampiamente utilizzato. Le buone implementazioni di BCrypt gestiranno la generazione di sale e la calibrazione/rilevamento automatico del fattore di lavoro. Dovrai implementare queste cose da solo per usare PBKDF2 e quasi inevitabilmente commetterai degli errori.

In quarto luogo, esiste un approccio esistente a ciò che sembra stia cercando di fare. L'autenticazione a conoscenza zero può essere eseguita con SRP . La password dell'utente non viene mai trasmessa via cavo e un uomo in mezzo non può annusare nulla di utile con cui autenticarsi. Tuttavia, è apparentemente difficile implementarlo correttamente e non ci sono molte librerie esistenti per farlo, il che dovrebbe darti un'indicazione di quanto sia effettivamente difficile il problema.

Per farla breve: non inventare la tua criptovaluta. Utilizzare soluzioni e protocolli che sono ampiamente implementati e hanno resistito alla prova del tempo.

7
Stephen Touset

L'hash sul client può essere una buona idea in alcune circostanze e per alcuni motivi, ma non renderei la "tranquillità dell'utente" una di queste. Sono tutto per gli utenti di essere in uno stato d'animo armonioso e tutt'uno con l'Universo, ma trovo dubbia l'idea di promuovere un modo per indurre gli utenti a riutilizzare la stessa password su più siti.

Un buon caso per l'hash sul lato client è il modo in cui funzionano alcuni "salvadanai password": calcolano una password specifica del sito eseguendo l'hashing della "password principale" dell'utente insieme al nome del sito. Ciò offre la maggior parte dell'usabilità di utilizzare sempre la stessa password ovunque, senza fornire la password principale a decine di siti distinti. Ma questo funziona solo finché l'algoritmo di derivazione della password è generico e non cambia; questo sembra essere molto meglio affrontato da un'estensione del browser Web che da un'applet proveniente dai siti stessi (tutti i siti dovrebbero cooperare in modo da utilizzare applet che utilizzano lo stesso algoritmo di derivazione della password, con dati specifici del sito).

Un altro buon caso per l'hash della password sul lato client è quando viene usato un hash lento (in modo da rendere più difficile la violazione della password per un utente malintenzionato che potrebbe prendere una copia del database di password con hash); è allettante tentare di scaricare i costi nel client, poiché, quando il client desidera connettersi, è principalmente inattivo e attivamente interessato alla connessione. Tuttavia, l'hashing lento è un corsa agli armamenti tra attaccante e difensore. L'uso di Java indurrà un rallentamento (di un fattore tipico di 3) e alcuni sistemi client possono essere piuttosto deboli (ad esempio smartphone economici o computer di dieci anni). È come raccogliere una spada invece di un fucile d'assalto prima di entrare in una battaglia in cui l'avversario porterà un carro armato).

Ma se ciò che vuoi, come utente, è proteggere la tua password da procedure di archiviazione sciatte da parte di un sito, allora il modo giusto per farlo è per scegliere una password diversa per ogni sito. (Personalmente, tengo un file di password e tutte le mie password sono generate casualmente.)

6
Thomas Pornin

Un dipendente di Google sta lavorando a qualcosa di simile chiamato TLS-OBC. Questa bozza RFC consente al client di eseguire l'hashing della password e di associarla a una sessione TLS.

In particolare potresti essere interessato a questo sito Web http://www.browserauth.net/Origin-bound-certificates

e questo link su Strong User Authentication http://www.browserauth.net/strong-user-authentication

::Aggiornare

OBC e forse l'altro è ora integrato nello standard di autenticazione FIDO.

4

L'obiettivo principale dell'hash della password è impedire a chiunque tranne l'utente di apprendere la password. Le persone le riutilizzano e di solito non sono molto forti se memorizzate. Ecco perché ci preoccupiamo di hash lenti (PBKDF2, Bcrypt, Scrypt, Argon2, qualunque cosa) invece di un hash veloce: protegge meglio la password dell'utente, anche se non ha alcun vantaggio per l'applicazione. Un vantaggio secondario di avere l'hash del server qualunque cosa accada prima di archiviarlo nel database, è che qualcuno che compromette il database non può accedere con nessuno dei valori hanno trovato (devono prima romperli).

Vogliamo mantenere entrambi i vantaggi. A tal fine, sostengo che dovremmo eseguire l'hash sul server e il client.

Perché sul server?
In modo che un utente malintenzionato che ha ottenuto il database non possa utilizzare i dati ottenuti per accedere. Se il tuo client ha già un hash lento, questo può essere un singolo round di alcuni algoritmi di hashing sicuri (come SHA-3 o BLAKE2) .

Perché sul client?

  1. Trasparenza
    Ogni volta che una società viene violata, dobbiamo sperare che ci dica come sono state sottoposte a hash le password, se non del tutto. Ci sono ancora posti che li memorizzano in chiaro, o usano un algoritmo veloce, o non li salano, ecc. Facendo hashing sul lato client, chi è interessato può vedere come viene fatto e prevenire domande come queste =. Mia madre non lo controllerà, ma anche mia madre non controlla il TLS di un sito Web per essere sincero: "hacker etici" o hacker con cappello bianco lo fanno.
  2. Rilevazione di compromesso
    Un argomento comune è che "se il server è compromesso, gli aggressori potrebbero rimuovere il codice JavaScript responsabile dell'hashing della password, consentendo agli aggressori di ottenere comunque il testo in chiaro". Questo argomento è valido solo per i siti Web, ma le persone di solito non lo menzionano, risultando nel fatto che nessuno hash lato client nelle applicazioni. Quello che dimenticano inoltre è che, se l'hashing lato client è comune, i ricercatori della sicurezza possono iniziare a usarlo: ci saranno persone che scansionano siti Web importanti per vedere se l'hashing è ancora lì (sarebbe piuttosto un indicatore di compromissione se Paypal rimuove hashing lato client (nel caso ipotetico in cui farebbero hashing lato client in primo luogo)) e potrebbero esserci estensioni del browser (o funzionalità integrate) che ti avvisano se viene rimosso, proprio come avvisiamo per il login moduli su pagine http.
  3. Migliora lo standard
    Ora che possiamo vedere l'implementazione di tutti, ci sarà un dibattito su chi ha ottenuto il più lungo e chi ha ottenuto il meglio. Questa discussione spinge sicuramente i cattivi a fare meglio, e probabilmente porta anche alla standardizzazione. Sarebbe davvero bello se potessi semplicemente aggiungere un parametro all'elemento di input della password, come <input type=password hash=v1>, che farebbe tutto l'hashing per te (salerebbe con il campo nome dominio e nome utente, ma tutti quei dettagli di questa proposta vanno oltre lo scopo di questa risposta).
  4. Scaricare il server
    Un rischio di eseguire hash molto lenti sul server è che un utente malintenzionato può utilizzarlo per un attacco denial of service: se il server ha bisogno di 2 secondi per elaborare ogni tentativo di accesso, gli aggressori hanno un enorme vantaggio nel provare a prendere giù. Eseguendo l'hash lento sul client (la cui CPU è inutilizzata il 99% delle volte in ogni caso, e non è come se la maggior parte delle persone accede a qualcosa più di alcune volte al giorno), si scarica il server, consentendo di scegliere hash più lenti senza rischiare che un utente malintenzionato distrugga il server.
  5. Nessun ficcanaso segreto
    Anche se eseguono l'hash del database, i dipendenti possono intercettare la password prima che venga hash e archiviata (accedendo a un punto di terminazione TLS o installando un codice aggiuntivo). Ci sono abbastanza storie di dipendenti aspri, o persino di adolescenti che creano applicazioni che potrebbero pensare che sia divertente guardare le password dei loro utenti (ero una di quelle, tanto tempo fa).
  6. Nessuna email in chiaro
    Se il server non ha la tua password, non può inviarti email come "Grazie per esserti registrato, il tuo nome utente e la tua password sono xxx". L'e-mail è comunemente considerata non sicura, ma ci sono ancora siti Web che lo fanno.
  7. Nessuna esposizione accidentale
    Di recente si è verificato un incidente in cui le password sono state scritte accidentalmente nei file di registro. Non menzionerò il nome della società perché non credo sia pertinente, ma era una grande azienda tecnologica con un team di sicurezza dedicato e tutto il resto. Incidenti come questi accadono e basta. Esiste inoltre un'esposizione in molte reti in cui un sistema separato esegue la terminazione TLS e quindi invia la richiesta in chiaro ad altri sistemi, consentendo a qualsiasi box di rete di vedere le password (Google era solito farlo fino a quando non si fosse accorto del NSA ha intercettazioni nella loro rete interna. Questo sarebbe un problema molto meno (ci sarebbe molta meno esposizione) se facessimo un hashing lato client.
  8. Ridurre l'impatto della trasmissione compromessa
    Se per qualche motivo il canale di trasmissione sicuro fallisce, ad esempio un bug in TLS, l'impatto viene ridotto perché un utente malintenzionato sarebbe in grado di osservare gli hash anziché la password originale. Ciò vale anche quando qualcuno è in grado di decrittografare uno stream crittografato anni dopo, ad esempio perché RC4 è ormai noto per essere stato interrotto più di qualche anno fa.
  9. Perchè no?
    Non riesco a pensare a nessun motivo per cui dovresti no farlo, supponendo che tu faccia anche un hash rapido sul server (per ottenere quel vantaggio secondario menzionato nel primo paragrafo). Anche se pensi che solo uno dei motivi sia convincente, sarebbe comunque un miglioramento.

[~ ~ #] faq [~ ~ #]

Penso che l'unica ragione per cui l'hash sul lato client non è la norma, è perché nessun altro lo fa. Ogni volta che qualcuno lo propone, tutti pensano "allora perché non lo facciamo già? Ci deve essere un motivo!" e iniziare a mettere in discussione i vantaggi o inventare ragioni illogiche. Se i motivi sopra indicati non sono già sufficienti, fammi provare a confutare alcune delle domande che ho sentito prima:

  • "Ma in un utente malintenzionato rimuoverebbe semplicemente il codice responsabile dell'hashing!" Questo vale solo per le applicazioni web. Le applicazioni normali (tra cui le applicazioni mobili) non presentano questo problema.
  • "Ma il mio caso si applica a un'applicazione Web!" Se l'hashing sul lato client sarebbe comune per le applicazioni Web, creeremmo dei controlli per questo: le persone costruiranno le estensioni del browser e scansioneranno i siti Web per vedere se l'hash è ancora lì e saranno in grado di emettere un allarme se improvvisamente scompare. Potrebbe esserci anche una standardizzazione. Tutti dei punti precedenti continuano a essere validi, anche nel caso di un'applicazione web.
  • "Ma qualunque sia il risultato [dell'hash lato client] è IS la password!" Lascia che ti faccia una domanda: se il tuo database di accesso è compromesso, pensi davvero che sia probabile che un l'utente malintenzionato deve ancora accedere alla propria applicazione per ottenere tutti i dati da essa? La difesa in profondità della maggior parte dei sistemi non è poi così buona, ma anche se lo è, l'argomento è nullo perché il consiglio è di fare un ulteriore hash rapido sul server.
  • "Ma dovresti semplicemente usare un gestore di password invece di affidarti alla sicurezza degli hash!" Sono d'accordo, sarebbe l'ideale. Autenticazione a due fattori ovunque, utilizzata da tutti, con gestori di password e smart card ... sì, quando arriva quel giorno, non abbiamo più bisogno dell'hash delle password. Dovresti comunque eseguire un hash veloce sul server per il suddetto vantaggio secondario, ma possiamo smettere di fare algoritmi di hash lenti e hash lato client perché nessuno riutilizzerebbe comunque le password.
  • "Ma non dovresti mettere l'utente responsabile della sicurezza!" Sono già responsabili della sicurezza: puoi sempre scegliere di avere 123456 come password (o se ci sono requisiti sciocchi, puoi ancora fare "Bailey2009!"). Puoi anche pubblicare le chiavi sulla tua connessione TLS e annullarne la sicurezza. L'utente sarà sempre in grado di rovinare qualsiasi sicurezza implementata, se lo desidera.
  • "Ma come salerai l'hash?" Il campo nome utente. Un sale non è segreto, solo unico, proprio come il campo del tuo nome utente.
1
Luc