Zero Knowledge Password Proof: perché l'hashing della password sul lato client non è un ZKP?

5

Scenario:

  1. Il client invia il suo nome utente u al server.
  2. Il server estrae una tupla sotto forma di (username, salt, hashed_password) dal suo database, dove username corrisponde al nome utente del client u . hashed_password è il risultato di hash(salt + password) (dove hash è una moderna funzione di hash crittografica) che è stata calcolata quando la tupla è stata scritta nel database (ad esempio durante la registrazione dell'utente).
  3. Il server invia salt al client.
  4. Il client calcola h := hash(salt + password) e invia h al server.
  5. Il server confronta h con hashed_password e concede l'accesso se l'hash corrisponde.

Se supponiamo che il server non abbia calcolato l'hash durante la registrazione dell'utente (invece, il client ha calcolato l'hash e inviato la tupla (username, salt, hashed_password) al server per poterla archiviare nel database), perché questo scenario non considerato una prova di password a conoscenza zero? O è in realtà un ZKP?

Da quanto ho capito il server non ha mai visto la password attuale, ma può essere verificato che il client possieda la password originale che è stata utilizzata per creare l'hash iniziale.

    
posta watain 01.02.2017 - 09:42
fonte

2 risposte

6

Il problema principale del tuo protocollo è che la seconda risposta del cliente è vulnerabile agli replay attack . Durante la procedura di accesso, un utente malintenzionato impara u e h che possono essere riutilizzati in un secondo momento in un accesso malevolo da parte dell'utente malintenzionato e determineranno un accesso corretto.

Suggerirei di utilizzare l'autenticazione challenge-response con HMAC qui, il che significa che il client riceve una richiesta dal server e restituisce la sfida firmata HMAC (= risposta).

  • Supponendo che il client conosca la password, il client è in grado di firmare messaggi (simmetricamente usando HMAC)
  • Dal punto di vista del server, il client si autenticherà firmando un messaggio fornito dal server

Protocollo ingenuo per comprendere l'idea:

1. [C] –––(username)–––> [S]

Attaccante: impara il nome utente (eventualmente potresti cambiarlo alla fine)

2. Server calculates M = (nonce) and stores M

nonce : un gruppo di byte casuali che DEVE essere univoci, impedisce attacchi di riproduzione. Per renderlo unico, aggiungi un timestamp o un contatore di login, ad esempio.

2. [C] <––– M ––– [S]

Attentatore passivo: l'attaccante apprende M che è diverso per ogni tentativo di accesso, anche per lo stesso utente. Senza conoscere la password, l'autore dell'attacco non può firmarlo.

Attaccante attivo: manipolare M non aiuta nulla: il client firmerà la M sbagliata che non sarà accettata dal server più tardi.

3. [C] ––– HMAC(M, pw) –––> [S]

Attentatore passivo: apprende la firma HMAC (M, pw). La firma HMAC non può essere riutilizzata perché M è sempre diversa (è per questo che deve essere unica).

Attaccante attivo: la manipolazione di M o della firma HMAC fa sì che la firma non sia valida o non corrisponda alla M memorizzata nel server al punto 4.

4. Server examines if the received M equals the stored M and verifies the HMAC signature

Questo è possibile perché il server conosce anche la password.

Questo protocollo soddisfa la mia interpretazione della definizione molto sciolta di wikipedia di ZKPP in quanto è interattiva e la conoscenza delle prove del cliente di dati derivati da password e non la password stessa.

In generale, il livello di sicurezza di zero prove di conoscenza si basa su procedure iterative che il mio tentativo ingenuo non copre. Consiglierei di dare un'occhiata a CHAP e / o SRP.

    
risposta data 01.02.2017 - 15:11
fonte
4

Il tuo esempio rimuove la nozione di hashing del tutto: H (S + P) diventa una password in chiaro che può essere riutilizzata direttamente senza alcun lavoro extra.

    
risposta data 01.02.2017 - 09:51
fonte

Leggi altre domande sui tag