Vale la pena hashing password sul lato client


132

Quando voglio mettere in atto un sistema di accesso, confronto sempre l'MD5 della password data con il suo valore nella tabella degli utenti sul lato server.

Tuttavia, un mio amico mi ha detto che una password "chiara" poteva essere annusata da un software di rete.

Quindi la mia domanda è: è una buona idea hash la password sul lato client? È meglio che cancellarlo dal lato server?


1
Stavo pensando di eseguire l'hashing della password sul lato client, ma solo così posso essere certo che la password del client non esiste mai come testo chiaro sul lato server, il che significa che possono sentirsi più facili sapendo che non conosco la loro vera password, o non posso rinunciare facilmente se compromesso. sono pazzo?
Ciclone,

1
Solo per completezza, dal momento che stiamo parlando di sicurezza, e MD5 è stato menzionato nell'OP: si dovrebbe sempre usare un salt quando si crittografa una password. L'utilizzo di MD5 semplice e non salato è solo leggermente migliore della memorizzazione di password in chiaro nel database.
Sffc,

1
@Cyclone Hashing SOLO sul lato client è sicuramente una cattiva idea, poiché se l'attaccante in qualche modo conosce l'hash, può usarlo per accedere come se conoscesse la password, bypassando il codice di hashing sul lato client.
Teejay,

5
@Teejay: ecco perché non invii l'hash in chiaro. Il server invia un salt casuale al client, si aggiunge l'hash della password e si esegue nuovamente l'hash del tutto, quindi si rinvia al server che esegue lo stesso calcolo. Un attacco replay fallisce perché il sale sarà diverso
MSalters il

2
Questa domanda non dovrebbe essere risolta su security.stackexchange.com?
efr4k,

Risposte:


115

Fondamentalmente, il tuo amico ha ragione. Ma semplicemente l'hashing della password sul lato client è semplicemente meglio che inviarla come semplice testo al server. Qualcuno, che può ascoltare le tue password in testo semplice è sicuramente anche in grado di ascoltare le password con hash e utilizzare questi hash acquisiti per autenticarsi sul tuo server.

Per questo motivo, i protocolli di autenticazione più sicuri di solito saltano attraverso un numero di cerchi per assicurarsi che un tale attacco di replay non possa funzionare, di solito, consentendo al client di selezionare un gruppo di bit casuali, che sono sottoposti a hash insieme alla password e inviato anche in chiaro al server.

Sul server:

  • generare alcuni bit di random
  • invia questi bit (in chiaro) al client

Sul cliente:

  • generare alcuni bit casuali
  • concatena la password, i bit casuali del server e i bit casuali del client
  • genera l'hash di quanto sopra
  • invia bit casuali (in chiaro) e hash al server

Poiché il server conosce le proprie informazioni casuali e i bit casuali del client (li ha ottenuti come testo in chiaro), può eseguire essenzialmente la stessa trasformazione. Questo protocollo assicura che nessuno che ascolti in questa conversazione possa utilizzare le informazioni in un secondo momento per autenticarsi in modo errato utilizzando le informazioni registrate (a meno che non sia stato utilizzato un algoritmo molto debole ...), a condizione che entrambe le parti generino ogni volta "bit di rumore" diversi, si stringe la mano.

Modifica Tutto questo è soggetto a errori, noioso e un po 'difficile da correggere (leggi: sicuro). Se mai possibile, prendi in considerazione l'uso di implementazioni del protocollo di autenticazione già scritte da persone esperte (a differenza di me! Quanto sopra è solo dalla memoria di un libro che ho letto qualche tempo fa.) In realtà non vuoi scriverlo di solito.


5
Come può eseguire l'autenticazione con la password con hash nel sistema di accesso poiché verrà nuovamente hash?
Zakaria,

4
Se memorizzi le tue password in forma con hash sul server (come dovresti), il client dovrà eseguire l'hashing della password due volte: prima, solo la password, quindi corrisponde alla visione del mondo sul server, quindi come descritto sopra per per il bene del protocollo.
Dirk,

3
@Dirk, poiché l'attaccante può annusare in entrambi i modi, i "bit casuali" verrebbero annusati. Quindi l'attaccante può analizzare (leggi: forza bruta) la coppia richiesta e risposta offline per trovare la password originale.
Pacerier,

7
Tuttavia, allo scopo di inviare una password o l'hash di una password, spesso viene utilizzato un processo asimmetrico come Diffie-Hellman per stabilire una chiave di crittografia che consente a entrambe le parti di scambiare informazioni senza che una parte ficcanaso sia in grado di decrittografarle. Questo è esattamente ciò che fa SSL, ed è il motivo per cui la maggior parte dei siti ha la propria pagina di accesso su HTTPS / SSL. SSL protegge già dagli attacchi di riproduzione. Consiglierei di sfruttare SSL piuttosto che costruire il proprio protocollo. Anche se sono d'accordo con salting + hashing sul lato client della password, ma li invio attraverso una connessione SSL stabilita.
AaronLS

14
Giusto per essere chiari: se non si utilizza HTTPS, non importa quale javascript si esegue sul client; un MITM sarebbe in grado di modificare i contenuti della tua pagina prima che colpisca il client. HTTPS è l'unica soluzione.
Aidan il

60

Prima di tutto, questo NON migliora la sicurezza della tua applicazione (supponendo che sia una webapp).

Usa SSL (o in realtà TLS, che è comunemente chiamato SSL), non è molto costoso (misura il tempo che stai usando per trovare modi per aggirarlo e moltiplicarlo con il salario minimo, l'acquisto di un certificato vince quasi sempre).

Il perché di questo è semplice. TLS risolve un problema (se utilizzato con i certificati acquistati, non autofirmato) che è piuttosto grande nella crittografia: come faccio a sapere se il server con cui sto parlando è il server con cui penso di parlare? I certificati TLS sono un modo per dire: "Io, l'autorità di certificazione, ritenuta attendibile dal tuo browser, certifica che il sito Web su [url] ha questa chiave pubblica, con una chiave privata corrispondente, che (chiave privata) solo il server conosce, guarda Ho firmato la mia firma su tutto il documento, se qualcuno l'ha modificato puoi vedere ".

Senza TLS, qualsiasi crittografia diventa inutile, perché se mi siedo accanto a te in un coffeeshop, posso far pensare al tuo laptop / smartphone che io sia il server e MiTM (Man in The Middle). Con TLS, il tuo laptop / smartphone urlerà "CONNESSIONE NON AFFIDATA", perché non ho un certificato firmato dall'autorità di certificazione che corrisponde al tuo sito. (Crittografia vs. autenticazione).

Disclaimer: gli utenti tendono a cliccare a destra attraverso questi avvertimenti: "connessione non attendibile Quello che voglio solo le mie foto di gattini??! Aggiungi eccezione Clicca Conferma Click YAY! Gattini!"

Tuttavia, se non si desidera acquistare un certificato, implementare comunque l'hashing javascript sul lato client (e utilizzare la libreria standford (SJCL) per questo, NON IMPLEMENTARE MAI CRYPTO ).

Perché? Riutilizzo della password! Posso rubare il tuo cookie di sessione (che mi permette di fingere al tuo server che io sono te) senza HTTPS facilmente (vedi firesheep). Tuttavia, se aggiungi un javascript alla tua pagina di accesso che, prima di inviare, esegue l'hashing della tua password (usa SHA256 o, meglio ancora, usa SHA256, invia loro una chiave pubblica che hai generato e quindi crittografa la password con hash con quella, non puoi usare un salt con questo), quindi invia la password con hash / crittografata al server. RIPRENDI l'hash sul tuo server con un salt e confrontalo con ciò che è archiviato nel tuo database (archivia la password in questo modo:

(SHA256(SHA256(password)+salt))

(salva il sale come testo normale anche nel database)). E invia la tua password in questo modo:

RSA_With_Public_Key(SHA256(password))

e controlla la tua password in questo modo:

if SHA256(RSA_With_Private_Key(SHA256(sent_password))+salt_for_username) == stored_pass: login = ok

Perché, se qualcuno sta annusando il tuo client, sarà in grado di accedere come client (dirottamento della sessione) ma non vedrà MAI la password in chiaro (a meno che non modifichi il tuo javascript, tuttavia, un hacker di Starbucks probabilmente non saprà come / essere interessato in questo.) Così avranno accesso alla tua webapp, ma non alla loro e-mail / facebook / ecc. (per il quale i tuoi utenti probabilmente useranno la stessa password). (L'indirizzo e-mail sarà il loro nome di accesso o sarà trovato nel loro profilo / impostazioni sul tuo webapp).


Penso che questa sia una buona risposta, ma probabilmente ha bisogno di qualche informazione in più su come salare correttamente e che è meglio usare una funzione di hashing "lenta" prima di archiviare la password sul server (come bcrypt).
Neyt,

24

Probabilmente stai bene non preoccuparti di questo - come dice Dirk anche se hai le password di hash un utente malintenzionato potrebbe essere su una rete e vedere l'hash ricevuto, e potrebbe semplicemente inviare lo stesso hash stesso.

È leggermente meglio, in quanto impedisce all'utente malintenzionato di sapere qual è la password, ma poiché può ancora accedere (o potenzialmente ricostruire la password originale ), non è molto utile.

In generale, se sei preoccupato per la sicurezza delle password e dei dati del tuo utente (e dovresti esserlo!), Ti consigliamo di utilizzare un server SSL sicuro. Se questo non è un problema per te per qualsiasi motivo, potresti non preoccuparti dell'hash; è solo sicurezza attraverso l'oscurità .


Modifica agosto 2014: Google sta spingendo sempre più fortemente i siti Web per passare a HTTPS ovunque , perché proteggere la comunicazione stessa è l'unico modo per prevenire attacchi di sniffing di rete. Tentare di offuscare i dati trasmessi ostacolerà, non fermerà, un attaccante dedicato e può dare agli sviluppatori un pericoloso falso senso di sicurezza.


Penso che la tua opinione che l'hash sul lato client sia solo "leggermente migliore" è vera se ti concentri esclusivamente sulla ricezione xdella password dell'utente e sull'accesso a un singolo servizio. Se consideri l'effetto collettivo, direi che è "molto meglio"; perché impedisce la creazione di grandi database di ricerca di password utilizzate per forzare gli hash salati su più servizi. IMO. Guarda cosa fa AWS Cognito nel client per riferimento.
f1lt3r,

17

In realtà non sono d'accordo sul fatto che l'hash sul lato client sia più sicuro in questo caso. Penso che sia meno sicuro.

L'intero punto di archiviare un hash della password nel database in contrapposizione alla password reale (o anche a una password crittografata) è che è matematicamente impossibile ottenere la password originale da un hash (sebbene sia teoricamente possibile ottenere una collisione input di hash, la cui difficoltà dipende dalla forza di sicurezza dell'algoritmo di hashing). Il possibile vettore di attacco qui è che se un potenziale attaccante in qualche modo compromettesse il database di archiviazione delle password, non sarebbe ancora in grado di ottenere le password originali dei tuoi utenti.

Se il tuo meccanismo di autenticazione invia un hash della password, quindi in questo scenario di violazione della sicurezza, l'attaccante non ha bisogno di conoscere la vera password: invia semplicemente l'hash che ha e hey presto, ha accesso all'account di un determinato utente, e per estensione, l'intero sistema. Questo in primo luogo sconfigge completamente il punto di memorizzare una password con hash!

Il modo veramente sicuro per farlo è inviare al client una chiave pubblica una tantum per poter crittografare la password, quindi decodificarla e ricodificarla sul lato server.

A proposito, questo tipo di domanda probabilmente avrà più risposte di esperti su Security StackExchange.


3
Completamente d'accordo con questo. Affinché un approccio lato client funzioni, si dovrebbe anche inviare il sale al client, il che invaliderebbe l'intero scopo della salatura!
James Wright,

@JamesWright: Il punto sta inviando un salt casuale per ogni uso, il che impedisce il riutilizzo illegale dei messaggi di accesso. (Una forma di attacchi replay). Inviare lo stesso sale ogni volta è davvero inutile.
Salterio

Quello che devi fare è usare un "nonce" ( en.wikipedia.org/wiki/Cryptographic_nonce ). In questo modo, il server controlla anche il salt e lo rende sicuro. Anche l'hash sul lato client è importante in modo che il codice JS iniettato non possa facilmente trovarlo in seguito. Maggiori informazioni qui: stackoverflow.com/a/21716654/43615
Thomas Tempelmann

Per utilizzare il sale + nonce in un processo di autenticazione di accesso, vedere questa risposta: stackoverflow.com/a/24978909/43615
Thomas Tempelmann

Ovviamente se lo hash sul lato client, dovrai hash di nuovo sul lato server per evitare il punto che stai sollevando. Come altri sottolineano, tuttavia, per la privacy si desidera già una crittografia lato client.
Daniel Methner,

5

Si noti che mantenere le password sicure contro terze parti non è tutto ciò che c'è da fare.

Non appena la privacy è coinvolto (e quando mai non è vero, in questi giorni?) Si non si vuole conoscere la password. Non puoi abusare o perdere ciò che non hai , quindi sia tu che i tuoi clienti potete dormire meglio se non vedete mai le loro password in chiaro.

Pertanto, hashing / crittografia lato client ha senso.


Concordato! Molte persone mancano questo punto. Se scarico il database delle password di password con hash salate e posso crackarne solo una utilizzando un database di ricerca hash, allora è probabile che riesca a decifrarle tutte. Una volta che ho 50k password originali, ora ho la chiave per gli xutenti sui nservizi che crittografano solo sul server. Se ogni servizio esegue l'hashing in modo univoco della password prima che lasci il client, l'ampio database di password cross-service diventa molto, molto più piccolo. Controlla il tuo traffico di accesso AWS, guarda cosa fanno. È probabile che il mio caro Watson.
f1lt3r,


1

Ho lavorato molto su questo recentemente, IRL ci sono due problemi con la crittografia hash / simmetrica lato client con davvero uccidere l'idea: 1. Devi riportare il sale sul server QUALCUNO ... e crittografare sul lato client avresti bisogno di una password ... che vanifica lo scopo. 2. Esponi la tua implementazione di hashing (non un affare ENORME in quanto la maggior parte dei siti usa uno dei 3 o 4 algoritmi di hashing) che rende l'attacco più semplice (basta provare uno invece di n).

Quello che alla fine sono andato è stata la crittografia asimmetrica sul client utilizzando OpenPGP.js o simile ... Questo si basa su una chiave generata dal lato client o importata sul client e sul server che invia la sua chiave pubblica. Solo la chiave pubblica del client può essere rispedita al server. Questo protegge dagli attacchi MIM ed è sicuro come il dispositivo (al momento memorizzo la chiave privata del client per impostazione predefinita in localStore, è una demo).

Il vantaggio principale di questo è che non devo mai avere i dati degli utenti archiviati / anche in memoria non crittografati sul mio server / archivio dati (e la chiave privata del mio server è fisicamente separata)

La base di ciò era fornire alle persone un modo per comunicare in modo sicuro laddove HTTPS fosse limitato (ad esempio, Iran / Corea del Nord ...) e anche solo un esperimento divertente.

Sono LONTANO dal primo a pensarci, http://www.mailvelope.com/ lo usa


1

Se qualcuno può vedere dentro e fuori i dati sulla tua connessione, l'autenticazione non ti salverà. Invece farei quanto segue per cose super segrete.

Le password sono state prehash sul lato client prima di essere inviate al server. (Il server memorizza un altro valore con hash e salato di tale hash inviato dal browser).

Quindi un attacco intermedio potrebbe consentire loro di inviare lo stesso valore hash per accedere come loro, ma la password dell'utente non sarebbe nota. Ciò impedirebbe loro di provare altri servizi con le stesse credenziali per accedere altrove.

I dati degli utenti sono crittografati anche sul lato browser.

Ah, quindi un attacco da intermediario otterrebbe i dati crittografati, ma non sarebbe in grado di decrittografarli senza la password effettiva utilizzata per accedere. (password dell'utente memorizzata nel DOM sul browser al momento dell'accesso). Quindi il vero utente vedrebbe i contenuti decifrati ma l'uomo di mezzo non potrebbe. Ciò significa anche che qualsiasi NSA o altra agenzia non sarebbe in grado di richiedere all'utente / alla società / al fornitore di hosting di decrittografare questi dati poiché sarebbe impossibile per loro farlo.

Alcuni piccoli esempi di entrambi questi metodi sono sul mio blog http://glynrob.com/javascript/client-side-hashing-and-encryption/


1

Recentemente sia GitHub che Twitter hanno annunciato che le password erano archiviate nei registri interni. Ho avuto questo accadere inavvertitamente in segnalazioni di bug e altri registri che si sono fatti strada in splunk ecc. Per Twitter se la password di Trump era nel registro potrebbe essere un grosso problema per un "vedere" un amministratore, per altri siti probabilmente non come un grosso problema in quanto gli amministratori non ne avrebbero molto da fare. A prescindere da amministratori, non ci piace vedere le password.

Quindi la domanda è davvero se l'hash deve avvenire sul lato client per motivi di sicurezza, ma come possiamo proteggere la password prima che alla fine venga l'hash e confrontata dal lato server in modo che non venga registrata in qualche modo.

La crittografia non è una cattiva idea perché gli sviluppatori devono almeno saltare alcuni cerchi e, se scopri che le password sono entrate nei log, puoi semplicemente cambiare la chiave di crittografia, distruggere l'originale e quei dati diventano inutili. Meglio ancora ruotare i tasti di notte e potrebbe ridurre notevolmente le finestre.

Puoi anche inserire un hash nel tuo record utente. Le password trapelate sarebbero password con testo in chiaro. Il server memorizzerebbe una versione con hash dell'hash. Sicuramente l'hash diventa la password, ma a meno che tu non abbia una memoria fotografica non ricorderai un byryp 60 caratteri. Salt con il nome utente. Se puoi raccogliere qualcosa sull'utente durante il processo di accesso (pur non esponendo che esiste il record dell'utente) puoi salare anche con quello creando un hash più robusto che non può essere condiviso tra i siti. Nessun uomo nel mezzo sarebbe in grado di tagliare e incollare l'hash catturato tra i siti.

Combinalo con un cookie che non viene reinviato al server e potresti trovarti su qualcosa. Alla prima richiesta invia un cookie al cliente con una chiave, quindi assicurati che il cookie non ritorni al servizio di accesso, quindi poche possibilità che venga registrato. Conservare la chiave in un archivio di sessioni, quindi eliminarla subito dopo il login o quando la sessione è scaduta ... questo richiede lo stato per voi ragazzi JWT, ma forse basta usare un servizio nosql per esso.

Quindi lungo la strada un amministratore si imbatte in una di queste password con hash e crittografate in splunk o in uno strumento di segnalazione di bug. Dovrebbe essere inutile per loro perché non riescono più a trovare la chiave di crittografia e anche se lo facessero devono forzare un hash. Inoltre, l'utente finale non ha inviato alcun testo in chiaro lungo la linea, quindi ogni uomo nel mezzo ha almeno un momento più difficile e non puoi semplicemente saltare su un altro sito e accedere.


Esattamente la mia preoccupazione. Se il server si registra in qualche modo per errore a causa di una cattiva implementazione o di intenzioni dannose, è possibile che altri account dell'utente possano essere compromessi se riutilizzano le password.
Dan,

0

Considera questo: -

Il client invia la richiesta al server "Ho una password per convalidare".

Il server invia al client una stringa casuale solo una volta. R $

Il client incorpora la password dell'utente in questa stringa (in base alle regole (variabili) che si desidera applicare).

Il client invia la stringa al server e, se la password è OK, il server accede l'utente.

Se il server riceve un'altra richiesta di accesso utilizzando R $, l'utente viene disconnesso e l'account viene bloccato in attesa di accertamento.

Ovviamente verranno prese tutte le altre (normali) precauzioni di sicurezza.


0

Questa idea di hashing lato client è di proteggere l'utente, non il tuo sito. Come già accennato più volte, sia il testo semplice che le password con hash hanno entrambi accesso al tuo sito allo stesso modo. Non ottieni un vantaggio in termini di sicurezza.

Ma i tuoi utenti, testo semplice, password devono essere conosciuti solo da loro. Sapere cosa hanno scelto come password sono informazioni che possono essere utilizzate contro di loro su altri siti e sistemi. Stai diventando un sito incentrato sul cliente proteggendolo dalla scoperta della scelta della password da parte degli sviluppatori del tuo server o di terze parti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.