Autenticazione con un server non attendibile

1

Ho chiesto una domanda correlata in precedenza, ma questa volta voglio chiedere una versione più ampia:

Per semplificare le cose, diciamo che ho sviluppato un'applicazione che consente agli utenti di inviare messaggi in una chat room e tra loro (simile a IRC). La natura del messaggio non richiede troppa segretezza, nulla di sensibile viene mai condiviso.

Sviluppo un server open source e un client open source per l'applicazione. Gli utenti configureranno i propri server, fornirò semplicemente i programmi server e client.

Voglio che gli utenti abbiano account su ciascun server. Il client dovrebbe idealmente accedere con un nome utente e una password.

Posso presumere che il cliente non ruberà le informazioni dell'account perché l'utente l'ha preso da una fonte attendibile. Il problema è che il server non può essere considerato attendibile perché:

  1. Il proprietario di ciascun server può apportare modifiche al codice del proprio server.
  2. Possono vedere il contenuto di qualsiasi database.

Come posso autenticare gli utenti:

  1. senza consentire al proprietario del server di accedere alla password dell'utente
  2. senza consentire al proprietario del server di accedere a un precursore della password di un utente (qualsiasi cosa che non sia la password, ma può essere trasformata nella password dell'utente o utilizzata per accedere a un altro server).
  3. senza fare affidamento su una chiave precalcolata che deve rimanere nascosta sul client o sul server (il codice sorgente lo rivelerebbe).
  4. idealmente consentendo una password Modifica: Idealmente la password e il nome utente sarebbero tutto ciò che sarebbe necessario per accedere, quindi collegandosi con macchine diverse l'utente avrebbe solo bisogno della password e del nome utente.

Gli approcci che ho in mente:

  1. Risposta alla sfida: inviare una sfida, cancellarla con una password e inviarla come risposta. Questo passa il requisito numero 1 e 3, ma fallisce il 2, in quanto richiede al server di avere anche accesso alla password con hash, che può essere trasformata nella password effettiva o utilizzata per accedere ad altri server (quest'ultimo è leggermente minore, dal momento che può essere affrontato se si verifica). La mia domanda altra va nei dettagli su come Ho implementato questa idea per i test.

    2: Whitelist server: sembra un po 'come barare, ma soddisfa tutti i requisiti "rimuovendo" il problema più grande, il fatto che il server non può essere considerato attendibile. Se il client tenta di connettersi a un server non presente nella whitelist, verrà emesso un avvertimento con una parola strong (oppure l'accesso ai server non autorizzati potrebbe essere completamente bloccato). Questo ha il rovescio della medaglia nel complicare il processo di creazione di nuovi server da parte degli utenti e pone su di me maggiori responsabilità del semplice sviluppo dell'applicazione (dovrei gestire la whitelist). Inoltre, non garantisce necessariamente che il server possa essere considerato affidabile poiché anche se il proprietario non è malintenzionato, non è garantito che abbia una protezione adeguata sui propri sistemi.

posta Selali Adobor 10.08.2014 - 08:01
fonte

4 risposte

1

Qualsiasi soluzione implicherà una crittografia a chiave pubblica. Ogni utente può avere una coppia di chiavi. La chiave segreta potrebbe essere crittografata con una password come suggerito da @Mark.

Se per qualche motivo non è pratico memorizzare una chiave privata e l'utente deve poter accedere utilizzando solo il software e una password, la chiave privata può essere generata al volo.

Puoi avere un database che contiene quanto segue per ogni utente:

  1. Dati utente

  2. A salt per la password dell'utente

  3. A salt for the public key

  4. Un hash della chiave pubblica (Fatto con il sale sopra)

Per autenticare:

  1. La password salt viene inviata al client.

  2. Il client combina la password salt e la password e usa questa combinazione per seminare un PRNG.

  3. L'output del PRNG viene utilizzato come input per qualsiasi algoritmo di generazione di chiavi private scelto dall'utente (RSA o qualsiasi altro algoritmo di firma).

  4. La chiave pubblica viene quindi inviata dal client al server.

  5. Il client deve anche dimostrare di detenere la chiave privata corrispondente (ciò potrebbe essere fatto firmando un'identificazione di sessione o tramite un protocollo sigma).

  6. Una volta che il server sa che il client ha la chiave segreta, convalida la chiave pubblica eseguendo l'hashing della chiave pubblica con la stored salt e confronta il risultato con l'hash memorizzato nel database.

L'ordine degli ultimi due passaggi è stato scelto per impedire a un utente malintenzionato che in qualche modo ha imparato la chiave pubblica (ma non la chiave privata) dall'apprendimento se quella chiave pubblica poteva essere utilizzata per accedere a un determinato account.

Non è necessario alcun hash iterato, poiché l'algoritmo per generare la coppia di chiavi tende ad essere sufficientemente intensivo dal punto di vista computazionale. A differenza dell'hash iterato, il calcolo della coppia di chiavi ha lo scopo secondario di mantenere le informazioni segrete ben nascoste dal server.

Se l'esistenza di un account utente deve essere nascosta, il server può simulare il protocollo quando viene fornito un nome utente non esistente come segue:

  • Nel primo passaggio dell'autenticazione genera una password pseudocasuale salt e invialo al client.

  • Segui il protocollo seguendo tutti i passaggi seguenti, a seconda del database.

  • Nell'ultimo passaggio dell'autenticazione calcola un hash e scarta il risultato. Rifiuta l'utente indipendentemente dal valore dell'hash.

La sfida rimanente nel nascondere l'esistenza di un account utente è come produrre una password psuedorandom che cambia ad una frequenza, che è indistinguibile dalla frequenza delle modifiche della password per un utente reale.

    
risposta data 10.08.2014 - 17:18
fonte
2

Sembra che tu voglia una crittografia a chiave pubblica simile a quella supportata da SSH. L'idea di base è che l'utente fornisca la propria chiave pubblica al server durante il processo di creazione dell'account, quindi dimostra la proprietà della chiave privata corrispondente durante la procedura di accesso.

La chiave pubblica, come suggerisce il nome, non è nemmeno lontanamente segreta, quindi soddisfa il requisito 1, non può essere utilizzata per costruire la chiave privata, quindi soddisfa 2, è calcolata al momento della creazione dell'account, quindi soddisfa 3, e sì, puoi usare una password per proteggere la chiave privata.

    
risposta data 10.08.2014 - 08:14
fonte
2

Utilizza i certificati. In questo modo il client non condivide mai la sua chiave privata con nessuno incluso il server. Il server ha solo la chiave pubblica dei client che non è segreta.

In alternativa, esegui una soluzione di identità federata o sfruttane una come Google o Facebook. Ci sono opzioni open source per questo (come link ) Inoltre non puoi essere completamente sicuro che il client non sia stato manomesso, ma nel tuo scenario non sembra comunque un problema.

    
risposta data 10.08.2014 - 08:19
fonte
0

Tutte e tre le altre risposte consentiranno a un utente di accedere senza che il proprietario del server possa vedere la password. Tuttavia, non forniscono realmente alcuna autenticazione . L'autenticazione è la conferma che è tu che accedi al tuo account.

In questo scenario, stiamo assumendo che l'amministratore del server abbia pieno accesso al DB (e questo probabilmente sarà il caso nella realtà). Ciò significa che l'amministratore può cambiare la password dell'utente in qualsiasi cosa gli piaccia, quindi accedere come tale utente (e inviare messaggi a tutti i suoi amici o leggere le sue chat private o qualsiasi altra cosa).

Penso che l'unico modo per aggirare questo problema sia controllarlo da qualche parte centralizzato. O implementa il tuo o utilizza soluzioni già implementate. Ciò potrebbe anche darti l'ulteriore vantaggio di un singolo account che funziona su più server, se vuoi implementarlo in questo modo.

    
risposta data 19.08.2014 - 17:41
fonte