Cosa trasferire? Password o il suo hash?

36

Diciamo che nel mio database memorizzo le password con hash con un hash abbastanza costoso (scrypt, 1000 round di SHA2, qualunque sia).

Al momento del login, cosa devo trasferire sulla rete e perché? Password o il suo hash?

È possibile proteggere tale accesso su un canale non crittografato come HTTP?

    
posta Konrad Garus 30.06.2011 - 14:47
fonte

4 risposte

57

Se si trasferisce l'hash dal client, questo non offre alcun vantaggio per la sicurezza e rende l'hash inutile:
Se un utente può accedere inviando l'hash al server, allora l'hash è effettivamente la password.

    
risposta data 30.06.2011 - 14:54
fonte
21

Se il tuo protocollo di autenticazione riguarda l'invio al server di una password, o un hash della password, con un semplice HTTP, allora questo è intrinsecamente molto debole, per due ragioni:

  • Qualcuno spiando la linea può registrare ciò che il client invia. Se l'invio di questi byte consente l'accesso, l'utente malintenzionato potrebbe semplicemente inviarli di nuovo. È un attacco di replay . Questo problema è ciò che allude @AviD nella sua risposta. Nessuna quantità di hashing lo risolverà. Alcuni protocolli tentano di correggere questo problema includendo una "sfida" dal server (un valore casuale, creato di nuovo per ciascuna connessione), da sottoporre a hash con la password sul client; questo è ciò che Autenticazione HTTP Digest riguarda.

  • Anche se l'autenticazione ha funzionato, questo è ancora un semplice HTTP, quindi qualunque dato verrà inviato in seguito sarà vulnerabile alle intercettazioni e alterazioni da parte di aggressori. Se il mezzo di trasporto non è protetto, l'autenticazione scoraggerà solo gli hacker più sofisticati. Qui è dove HTTP Digest fallisce.

Pertanto hai veramente bisogno di SSL (noto anche come HTTPS), non solo per comunicare la password o l'hash, ma anche il resto della conversazione tra client e server.

In futuro suppongo che il protocollo sia eseguito all'interno di un tunnel SSL. Hai ragione a voler usare un hash lento come bcrypt o PBKDF2; si noti che è necessario anche un sale per impedire la condivisione dei costi (ad esempio tabelle precompilate). L'hashing lento e salato viene utilizzato per far fronte alla debolezza intrinseca delle password. Ora, potresti voler scaricare parte dello sforzo di hashing sul client. Questo potrebbe funzionare, ma solleva alcuni problemi pratici:

  • Poiché l'elaborazione della password deve includere un salt, uno nuovo per ogni istanza di password, quindi il sale deve essere trasferito al client, in modo che il client possa includerlo nel processo di hashing che esegue. Ciò aumenta la complessità del protocollo: il client deve prima inviare il nome utente al server, quindi il server deve restituire il sale e (solo in quel momento) il client può iniziare a cancellare la password. Questo è un altro roundtrip della rete rispetto al solito "invia nome utente e password come una richiesta POST".

  • L'hashing lento consiste nell'accettare di spendere molta CPU su ciascuna password, in modo che l'attaccante anche debba spendere molto CPU su ciascuna password. Ma se la CPU spesa è sul client, non possiamo aumentarla quanto vorremmo, perché: 1) ci sono clienti che hanno pochissima CPU (ad esempio alcuni smartphone o tablet economici) e 2) il contesto Web implica usando Javascript, e le prestazioni di Javascript sono davvero pessime quando si parla di hashing (diciamo almeno 20 volte più lento del codice C).

Pertanto, la solita saggezza è che la parte dell'hash della password sul client non vale la pena.

    
risposta data 28.10.2012 - 16:54
fonte
4

Entrambe le opzioni non sono sicure.

Il trasferimento della password renderà il tuo testo semplice protocollo. Il trasferimento dell'hash ti renderà vulnerabile agli attacchi di riproduzione.

APOP è un'implementazione di accesso per il protocollo POP. Ciò consente al protocollo di mantenere la password privata da qualsiasi ascoltatore sulla rete. Uno svantaggio di questo è che sia il client che il server devono conoscere la password in formato testo, poiché questo è il segreto condiviso. Prima di quello del protocollo, sia il client che il server hanno < password > La comunicazione del protocollo è fondamentalmente così:

  1. Il client si connette al server e invia un token casuale (T1)
  2. Il server invia un token casuale (T2)
  3. Il client invia M = sha (T1 + T2 + < password: copia del client >) al server
  4. Il server verifica se sha (T1 + T2 + < password: copia del server >) corrisponde a M (l'hash appena ricevuto).

Qui il server conosce sia la magia che la password ed è in grado di determinare se l'utente conosce la password corretta senza esporla a nessun listener.

La migliore pratica sarebbe quella di archiviare in modo sicuro gli hash nel database e fare affidamento sui canali crittografati.

    
risposta data 30.06.2011 - 14:58
fonte
-1

Né, idealmente si usa un meccanismo di risposta alle sfide e poi si trasferisce quell'hash, e si fa tutto questo su un canale protetto da crittografia come SSL. Ma alla maggior parte degli utenti non piace che ci vogliano solo 5 minuti per accedere. Inoltre, l'utente dovrebbe controllare tutto questo prima di usarlo.

In definitiva dipende da quanta sicurezza si ha bisogno e da quali vettori di attacco si cerca di proteggere, ma usare SSL è sempre una buona idea.

    
risposta data 01.07.2011 - 22:12
fonte

Leggi altre domande sui tag