Come funziona la memorizzazione delle password hash? [duplicare]

27

Nelle normali applicazioni di rete, che utilizzano l'hashing della password, l'hash della password utente sul lato client prima di inviarlo al server o viene inviato senza hash come crittografia della password in testo semplice al server?

La domanda principale che ho è se un utente malintenzionato scopre le password con hash, quindi perché non possono semplicemente inviare hash al server per l'autenticazione in caso di hashing lato client?

    
posta Allahjane 13.04.2016 - 18:31
fonte

5 risposte

39

Almeno una parte dell'hash deve verificarsi sul lato server. In effetti, qualunque cosa il client invia al server concede l'accesso, quindi se lo stesso valore è appena archiviato come-è sul server, allora avete gli stessi problemi dell'archiviazione di password in chiaro, vale a dire un singolo sguardo di sola lettura sul vostro server database fornisce tutti gli accessi.

Nella maggior parte dei casi tutto l'hashing viene eseguito sul server, perché il client è un browser Web che può, nella migliore delle ipotesi, fare qualche Javascript, e Javascript non è molto bravo in attività crittografiche. Il client invia la password stessa (tramite HTTPS ovviamente) e il server calcola l'hash e lo confronta con il valore hash memorizzato. L'attaccante non può semplicemente "passare l'hash"; deve inviare un valore che, quando viene cancellato dal server, restituisce il valore hash memorizzato.

Se i client sono bravi a fare crypto (ad esempio un client nativo pesante per un gioco), allora la maggior parte del processo di hashing può essere eseguita sul lato client, ma deve ancora essere eseguito un calcolo hash finale server.

    
risposta data 13.04.2016 - 18:42
fonte
24

L'hashing della password di accesso è che si suppone funzioni

Si noti che in tutti i frammenti, sto escludendo intenzionalmente le funzionalità di sicurezza perché voglio mantenerlo compatto. Non fare affidamento su questi frammenti di codice per qualsiasi cosa.

In usual network applications ,that employ password hashing, is the user password hashed on client side before sending it to the server or is it sent without hashing as encryption of plain text password to the server?

No, è lato server con hash. Si invia la password su testo normale o tramite HTTPS al server. Il server genererà quindi un hash per la password, in questo modo:

public void RegisterAccount(string username, string password, string email)
{
     if (!Database.EmailExists(email) && !Database.UsernameExists(username))
     {
         Database.AddNewUser(username, Hash.GenerateHash(password), email);
     }
}

Supponi che Database.AddNewUser(string, string, string); inserisca il nome utente, la password hash e l'e-mail nel database. L'hash viene generato in base alla password.

Supponiamo che tu inserisca la parola d'ordine "non mi hackerare per favore". bcrypt lo trasformerà in $2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy , o qualche altra variante basata sul sale. Il database ora assomiglia a questo:

+--------------+--------------------------------------------------------------+--------------------+
|    user      |    password                                                  |       email        |
+--------------+--------------------------------------------------------------+--------------------+
| markbuffalo  | $2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy |   [email protected] |
+--------------+--------------------------------------------------------------+--------------------+

Normalmente chiamerai il database per leggere la password per quel nome utente. Una volta chiamato il database, si utilizzerà una funzione, ad esempio Hash.ValidateHash() , per verificare se corrisponde. Se corrisponde, puoi accedere usando quella password non hash.

Perché non puoi semplicemente passare l'hash per accedere?

In alcuni casi molto sfortunati .

The main question I have is if an attacker discovers the hashed passwords then why can't he just send hash to the server to authenticate in case of client side hashing?

Questo è possibile, ma può accadere solo durante le gravi occorrenze di errori epici massivi da parte degli sviluppatori. In effetti, l'ho già visto prima e ti mostrerò come ciò può accadere tramite codice:

public void Login(string username, string password)
{
    if (Database.LoginMatches(username, password) ||
        Database.LoginMatches(username, Hash.ValidateHash(password)))
    {
        logMeIn();
    }
}

Nel frammento di cui sopra, il login vuole verificare se l'utente ha l'hash o la password che verrà convalidata nell'hash memorizzato nel database. Questo è non il modo corretto per farlo. In effetti, è uno dei peggiori casi di fallimento epico che abbia mai visto in vita mia.

Con questo codice, puoi semplicemente inserire l'hash o la password e accedere. Richiama la tabella precedente. Uno dei seguenti accessi funzionerà correttamente:

  1. Login("markbuffalo", "$2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy");
  2. Login("markbuffalo", @"don't hack me please");

Questo è l'approccio sbagliato interamente. Non dovrebbe succedere. A. Tutti. Tuttavia, alcuni sviluppatori hanno adottato questo approccio per ragioni che non conosco.

Qual è l'approccio giusto per la convalida dell'hash?

Come Rápli András detto, h(x) non corrisponde a h(h(x)) . L'approccio giusto è quello di controllare la password in arrivo contro l'hash per vedere se corrispondono. Se non corrispondono, non utilizzare nessuna magia OR ( || ); semplicemente non permettere loro di accedere.

    
risposta data 13.04.2016 - 19:16
fonte
3

Alla tua prima domanda:

Dipende dall'applicazione. Nella maggior parte dei casi, la password viene inviata al server in chiaro (e questo non è sicuro se l'applicazione utilizza un protocollo non crittografato, come HTTP). Il server, tuttavia, potrebbe memorizzare un valore hash nel database. In tal caso, l'applicazione calcola il valore hash della password di testo non crittografato ricevuta dall'utente e la confronta con il valore memorizzato nel db.

Alla tua seconda domanda:

Il server si aspetta un input per la password: X . L'autore dell'attacco in qualche modo scopre h(X) . Quindi se inserisse questo valore di hash per l'autenticazione, la funzione di hash verrebbe eseguita ancora una volta contro h(x) , quindi non sarebbe in grado di entrare poiché h(x) non corrisponde a h(h(x)) .

    
risposta data 13.04.2016 - 18:35
fonte
1

Come altri hanno sottolineato, il modo normale per farlo è che il client invii la password non crittografata, ma su un canale sicuro (che utilizza crittografia reversibile, non hashing ) e quella password viene quindi hash sul lato server con lo stesso valore dell'hash memorizzato.

       Client      <----- Secure link ----->     Server
Cleartext password     Encrypted password    Hashed password
  1. Il cliente ha la password in chiaro.
  2. Il client crittografa la password (tramite TLS)
  3. Il server riceve la password crittografata, la decifra (tramite TLS)
  4. Password di hash del server con lo stesso valore memorizzato nel database per questo utente
  5. Il server confronta l'hash calcolato con l'hash memorizzato.

Protezione:

  • contro l'intercettazione (dovuta all'uso di un canale sicuro)
  • contro attacchi MITM (se la sessione TLS è impostata correttamente, certificati correttamente controllati, ecc.)
  • contro il furto del database delle password

Ora il problema è quando devi inviare una password su un canale che non fornisce la crittografia , come potrebbe essere il caso per il protocollo di basso livello (ad esempio PPP o 802.1X). Le scelte tradizionali (per PPP) erano:

  • PAP : invia la password in testo non crittografato, che può essere sottoposta a hashing lato server per il confronto con il database delle password con hash

  • CHAP : utilizza un protocollo challenge-response e invia una versione hash della password (combinata con la sfida e un id) tramite il link, ma ciò ha richiesto al server di memorizzare il testo in chiaro delle password

Quindi il primo protegge contro il furto del database delle password, ma non contro l'intercettazione, mentre la situazione è invertita per quest'ultimo.

Mettendo da parte i protocolli EAP che effettivamente impostano un tunnel TLS (PEAP, EAP-TTLS, EAP-TLS ...) per proteggere lo scambio di password, esiste un protocollo alternativo che consente l'invio di un "hash" non reversibile di la password di un server, che memorizza anche un "hash" della password: SRP , e più in generale "aumentata PAKE "protocolli.

    
risposta data 14.04.2016 - 18:35
fonte
0

Un attacco basato sul semplice invio di dati acquisiti (ad esempio una password che è stata sottoposta a hashing dal client) senza la necessità di decodificare i dati è noto come un attacco "replay". La mitigazione standard per questo attacco consiste nell'includere ciò che è noto come "nonce" nei dati con hash, questo potrebbe essere un numero casuale fornito dal server o un timestamp ragionevolmente ad alta risoluzione generato dal client. Il server verificherà quindi che il nonce sia valido o all'interno di un intervallo accettabile e, se è sbagliato o troppo vecchio, rifiuterà la richiesta. Una discussione dettagliata può essere trovata qui Qual è l'uso di un cliente nonce?

    
risposta data 14.04.2016 - 20:43
fonte

Leggi altre domande sui tag