Come inviare solo password con hash mentre non si memorizzano le password in chiaro sul server?

1

In un sistema di autenticazione basato sul web faccio quanto segue:

  1. Client: chiedi al server un "nonce".
  2. Cliente: genera un "cnonce".
  3. Cliente: hash (nonce + cnonce + password)
  4. Client: invia cnonce e l'hash dal punto 3 al server.

  5. Server: hash (nonce + cnonce + password)

  6. Server: confronta gli hash.

Questo mi imporrebbe di salvare le password in testo semplice / crittografato poiché il server ha bisogno di "password" per calcolare l'hash da confrontare.

Certo che non voglio farlo e quindi ho cancellato tutte le password salvate sul server con hash (password, salt). Ma ora non riesco a confrontarmi con l'hash che il client mi invia poiché non ho il componente della password.

Un modo per risolverlo sarebbe quello di fornire al client l'utente unico salt in modo che il client possa calcolare hash (nonce + cnonce + hash (password, salt)) e inviarlo al server, permettendo al server di confrontare gli hash. Ma secondo Come conservare il sale? il sale non dovrebbe mai essere condiviso.

Il motivo per cui utilizzo nonce su una connessione HTTPS è descritto in: Dovrei cancellare la password prima di inviarla al server?

Quindi la mia domanda è come uscire da questo ciclo infinito di "non fare"?

    
posta Gurgy 06.01.2017 - 16:21
fonte

3 risposte

2

Per riepilogare i commenti:

Non capisco appieno la risposta StackOverflow a cui ti stai riferendo. Nella tua spiegazione invii un nonce dal server al client su HTTPS che è considerato danneggiato in questo attacco. Quindi l'attaccante ottiene il nonce. Viene generato un cnonce e entrambi i nonces e la password sono sottoposti a hash.

Il cnonce e l'hash vengono inviati tramite la connessione HTTPS (presumibilmente insicura). L'attaccante ha ora il nonce, il cnonce e l'hash. Può provare a invertire l'hash per ottenere la password (bruteforce). Ma questo non è nemmeno necessario in quanto il server è disposto ad accettare l'hash e concedere l'accesso. L'attacco semplicemente rinvia l'hash. Come ha affermato @Matthew, hai appena creato un sostituto della password.

È possibile invalidare il server nonce dopo un'autenticazione, in modo che se l'hash viene reinviato, viene rifiutato. Questo sembra un miglioramento della sicurezza poiché l'hacker potrebbe riuscire solo invertendo l'hash che è molto difficile con password complesse e lunghe.

Lo sforzo supera il vantaggio? Penso di sì, HTTPS è considerato sicuro se configurato correttamente. L'intero Internet dipende da HTTPS per proteggere l'autenticazione, quindi, a meno che la tua applicazione sia molto sensibile, dovresti fare affidamento su di essa.

Buona fortuna per il compito!

    
risposta data 06.01.2017 - 17:00
fonte
0

L'obiettivo di sale è che diversi account avranno diverse password hash (con cui mi riferisco al risultato finale che memorizzi nel tuo db, dopo tutte le trasformazioni).

Pertanto, non è un problema che un utente malintenzionato impari il sale utilizzato per un determinato utente. Poteva iniziare a calcolare le possibili password hash, ma avrebbe avuto bisogno di una diversa tabella arcobaleno per l'utente, quindi non sarebbe utile eseguire tali calcoli prima di rubare il database.

Il problema con la condivisione di Salt con il client è che potresti perdere gli utenti esistenti sul tuo db, poiché gli utenti esistenti restituiranno sempre lo stesso sale (puoi offuscarlo restituendo un salt derivato dal nome utente specificato per utenti che non esistono realmente).

Si noti inoltre che, sebbene non si specifica quale sia esattamente l'operazione + negli hash di cui sopra, è necessario sostituire con hmac i passaggi di un hash dei valori combinati.

Ad esempio, supponendo che + fosse l'operatore di concatenazione, un attore malintenzionato che ha intercettato una richiesta di accesso con nonce = 123456789 e cnonce = 987654321, potrebbe banalmente impersonare una richiesta di accesso in cui il server ha fornito un nonce = 12345 (cioè. una maggiore probabilità di ottenere un nonce valido che ottiene esattamente esattamente lo stesso).

Potresti anche trovare interessante il protocollo Secure Remote Password ( RFC 5054 ). Sebbene entrambe le parti lavorino con password in chiaro, è possibile adattarle agli hash salati calcolati su entrambi i lati (la "password" è l'output dell'operazione salt).

Infine, devi capire che in questi schemi, l'hash salato è equivalente in testo normale, poiché è sufficiente per l'accesso. Puoi memorizzare quella password salata crittografata¹ con una password specifica per l'applicazione (avrebbe un ruolo simile a un pepe ), ma ciò nonostante le sue proprietà in caso di compromissione sarebbero un po 'diverse rispetto al solito approccio. Se qualcuno ha rubato il tuo database (ad esempio da un dump di sql in un backup non protetto), questo peperone -se non rubato con il db- sarebbe l'unica cosa in modo che l'attaccante gli impedisca di impersonare qualsiasi utente.

¹ sì, deve essere reversibile affinché il protocollo funzioni

    
risposta data 06.01.2017 - 17:31
fonte
0

Il server ha sicuramente bisogno di memorizzare un verificatore per ogni inserimento di password. I nostri verificatori saranno (user_salt, server_salt, server_hash) triple, dove:

  • user_salt e server_salt sono array a 16 byte casuali.
  • server_hash = keyedhash(server_salt, pwhash(user_salt, password)) , dove:
    • pwhash denota una funzione di hashing della password "lenta" come PBKDF2, bcrypt, scrypt o Argon2;
    • keyedhash indica una funzione di hash con chiave come HMAC-SHA2.

Ora possiamo usare un protocollo di autenticazione come questo:

  1. Cliente: invia username al server;
  2. Server: risponde con il corrispondente user_salt ;
  3. Cliente: calcola client_hash = pwhash(user_salt, password) ;
  4. Cliente: invia client_hash al server;
  5. Server: calcola server_hash = keyedhash(server_salt, client_hash) ;
  6. Confronta server_hash con il valore memorizzato nella voce della password dell'utente.

Il protocollo di modifica della registrazione / password è simile:

  1. Cliente: autentica con il server;
  2. Cliente: invia una richiesta di modifica della password;
  3. Server: risponde con una percentuale casuale dinew_client_salt;
  4. Cliente: calcola new_client_hash = pwhash(new_client_salt, new_password) ;
  5. Cliente: invia new_client_hash ;
  6. Server: seleziona un% casualenew_server_salt;
  7. Server: calcola new_server_hash = keyedhash(new_server_salt, new_client_hash) ;
  8. Server: memorizza (new_client_salt, new_server_salt, new_server_hash) come% nuova password diusername.

Entrambi i protocolli devono essere eseguiti su un canale autenticato e confidenziale (ad es. una connessione SSL). Un intercettatore che vede client_hash sarebbe in grado di impersonare l'utente.

Uno dei vantaggi di un protocollo come questo è che, oltre a non inviare mai la password sul canale, calcola la funzione di hashing della password lenta sul lato client, il che significa che è possibile aumentare il fattore di lavoro della funzione per rendere attacchi di password cracking più difficili.

Vedi anche questi link per proposte simili:

risposta data 06.01.2017 - 20:33
fonte

Leggi altre domande sui tag