Metodi per autenticare il client con un server

2

Ho un'app che invia un messaggio crittografato al server, con il mittente e il nome utente del destinatario allegati. I nomi utente sono collegati a un ID dispositivo univoco che consente di inviare messaggi tramite il servizio Google Cloud Messaging.

Il mio problema è che non sono sicuro di quale sia il modo migliore per impedire a chiunque di falsificare i messaggi sul server e scrivere qualsiasi possibile nome utente nel campo del mittente.

Speravo di poter usare solo una chiave segreta memorizzata nel codice dell'app che è la stessa di una chiave memorizzata sul server corrispondente a un utente specifico, ma da allora ho scoperto che questa chiave sarebbe soggetta a essere scoperta attraverso il reverse engineering dell'app.

Quindi ora l'unica soluzione apparente per me è implementare un sistema basato su password che genera una chiave di sessione a tempo limitato sul server che viene recuperata dal client dopo aver inviato la password corretta e quindi inviata insieme a ciascun messaggio successivo.

Tuttavia, preferirei evitare questo tipo di sistema perché voglio mantenere l'app il più semplice possibile ed evitare di dover implementare sistemi di password dimenticati e tali.

Ci sono altri modi in cui posso garantire che i messaggi siano autentici?

    
posta JackWoot 28.01.2014 - 03:35
fonte

2 risposte

2

Dal punto di vista crittografico, se un utente A deve essere in grado di fare qualcosa che un altro utente B non può (ad es. inviare un messaggio con " A "come nome del mittente), quindi deve esserci un valore che A sa, ma B no. Quel tipo di valore segreto è chiamato un tasto , sebbene ci siano altre terminologie (ad esempio "password" quando il segreto è memorizzato in un cervello umano).

Nascondere le chiavi all'interno del codice dell'applicazione presenta due principali svantaggi:

  • Possono essere ripristinati mediante reverse engineering.
  • Non sono specifici dell'utente.

Tuttavia, nel tuo caso, vuoi un valore segreto specifico dell'utente: ogni utente ha la sua chiave, con la quale i suoi messaggi sono autenticati. Pertanto, la chiave dell'utente non può essere codificata nel codice dell'applicazione compilato; tuttavia, può essere memorizzato come file sul dispositivo dell'utente. Reverse-engineering è qui un non-problema: invertendo la propria installazione dell'app, l'utente può apprendere la propria chiave, non la chiave di qualcun altro.

Il punto importante qui: tale chiave autentica l' utente , non il dispositivo . Assicurarsi che un dato messaggio provenga da uno specifico dispositivo e inviato da "la tua app non modificata" e non da altro codice, è praticamente impossibile, dal momento che il suddetto dispositivo è fisicamente nelle mani dell'utente, e non è resistente alla manomissione. Per ottenere questo tipo di garanzia, è necessario un dispositivo in grado di contrattaccare il suo proprietario, ad es. una smart card . La fatturazione del telefono cellulare funziona, sia in modo pratico che legale, in quanto l'utente non può accedere alla propria scheda SIM. Non puoi avere questo modello con un'app che è software solo su hardware non schermato (il telefono stesso).

Tuttavia, se vuoi autenticare gli utenti, non i dispositivi, allora una chiave specifica per l'utente va bene.

Poi arriva la parte difficile: l'autenticazione è buona, ma chi lo sta facendo?

Se vuoi solo che il tuo server si assicuri dell'identità di A , allora un segreto condiviso tra A e il server S può andare bene. Lo strumento crittografico sottostante sarebbe un MAC . Tuttavia, in questo caso, quando l'utente A invia un messaggio all'utente B attraverso il tuo server, il server è certo che in effetti parla con A , ma B non sa nulla. Un malvagio E , che vuole falsificare un messaggio falso proveniente da A , può inviare il messaggio direttamente a B , senza passare attraverso il tuo server a tutti!

Una soluzione, in questo caso, è rendere la comunicazione da S a B ugualmente autenticata con la chiave B : questa volta, questo è B che si assicura che ciò che riceve da S sia effettivamente da S . Con MAC applicato in entrambe le direzioni, per tutte le comunicazioni tra il server e qualsiasi utente, è possibile disporre di una rete di messaggistica ragionevolmente sicura. Certo, S è fidato : il tuo server può tradire tutti a piacimento. Ma forse questo non è un problema per te.

(per l'autenticazione end-to-end, senza affidarsi a un server centrale, è necessario ricorrere alla crittografia asimmetrica e alle firme digitali , e le cose diventano molto più complesse.)

La memorizzazione di una chiave specifica dell'utente in un file sul dispositivo dell'utente sembra abbastanza semplice. Tuttavia, a volte, gli utenti cambiano dispositivo (ad es. Acquistano un nuovo telefono, oppure sono dipendenti Apple che hanno un iPhone e un iPad) e desiderano mantenere la loro identità . Ciò implica che la chiave specifica dell'utente viaggi in qualche modo da un dispositivo all'utente.

Lo schema che prevedi (memorizzare la chiave sul server stesso, con download automatico dopo l'autenticazione basata su password) è valido. Assicurati di farlo su SSL, ovviamente. Puoi combinarlo con un meccanismo di memorizzazione nella cache: l'app scarica la chiave quando non la ha già, ma poi la memorizza sul dispositivo.

    
risposta data 28.01.2014 - 14:54
fonte
0

Dal momento che è un'app, presumo che sia per dispositivi mobili? In tal caso, si consiglia vivamente di utilizzare il protocollo TLS consolidato. Fornisce riservatezza, autenticazione dei messaggi e integrità tramite l'uso di codici di autenticazione dei messaggi e di crittografia (MAC). Non richiede l'archiviazione di alcuna chiave nell'app se acquisti un certificato di chiave pubblica per il tuo server. Inoltre, sono disponibili librerie SSL / TLS per Android SDK e iOS.

Altrimenti, se implementi il tuo schema di autenticazione dei messaggi e il protocollo di handshake, potrebbe non essere abbastanza sicuro e soggetto a errori di implementazione.

    
risposta data 28.01.2014 - 06:21
fonte

Leggi altre domande sui tag