Chiave pubblica nelle risorse per evitare l'uomo nell'attacco centrale

2

Sto sviluppando un'applicazione Android che deve comunicare con un server web. Invece di usare SSL comune, vorrei salvare la mia chiave pubblica personalizzata nelle cartelle delle risorse dell'applicazione (file di installazione APK), quindi prima di iniziare a inviare o ricevere dati sul dispositivo, il primo server richiede una chiave segreta condivisa dal dispositivo che viene crittografata tramite chiave pubblica. L'uomo nell'attacco è possibile in questo scenario?

Aggiornamento: Il metodo che voglio usare è chiamato "pinning del certificato" ed è comune sono alcuni casi d'uso. link

    
posta Ali 20.04.2015 - 11:05
fonte

3 risposte

1

Quello che stai chiedendo è fondamentalmente ridefinendo il "SSL comune". Tuttavia, si basa la fiducia solo sul server, mentre in SSL il trust è delegato a una terza parte. Inoltre, i certificati SSL sono firmati, pertanto è possibile verificarne l'autenticità.

Quindi sì, lo scenario sarà in grado di prevenire l'attacco MitM (in un certo senso), ma l'utente perde fiducia nel processo (rispetto a SSL) perché:

  • non c'è più verifica della chiave
  • non c'è nessuno che possa garantire la tua identità come farebbe un'autorità di certificazione

Uno scenario che potrebbe essere escogitato per eseguire MitM potrebbe essere qualcuno che manomette l'APK per cambiare la chiave pubblica per sostituirla con un'altra su cui ha il controllo. Questo probabilmente non è tecnicamente facile ma neanche impossibile.

Infine, sarebbe meglio usare una versione recente della suite SSL / TLS piuttosto che sviluppare il proprio protocollo.

    
risposta data 20.04.2015 - 11:23
fonte
1

Quello che stai suggerendo è completamente compatibile con il framework Android TLS.

Quando crei una connessione a un server remoto, puoi specificare la tua lista di CA di fiducia . Ciò significa che, invece di utilizzare l'archivio CA predefinito attendibile dal sistema operativo, per questa connessione ci si fida solo dei certificati firmati dalle CA specificate, che non devono essere noti a nessun altro.

Allo stesso modo, puoi spedire i certificati client che saranno richiesti e verificati dal server al momento della connessione. Tutto questo fa parte delle specifiche, quindi niente di ciò che si vuole fare deve essere implementato su misura. Puoi contare su protocolli e codici consolidati e testati.

Se le connessioni al tuo servizio saranno effettuate solo dai clienti che spedisci, allora questa è in realtà una best practice consolidata. Non c'è motivo di firmare i certificati da una CA di fiducia globale se sei l'unico a fidarsi di loro e non c'è motivo di fidarsi delle CA comuni se sai che il tuo certificato non sarà firmato da loro.

Anche in questo caso, usa le cose incorporate. La regola numero uno di crypto è non creare il proprio . Non andrà bene se lo fai.

    
risposta data 21.04.2015 - 07:53
fonte
1

Stai complicando le cose e riducendo la sicurezza senza motivo. Usa SSL¹ - perché mai non lo useresti? L'intero punto di SSL è evitare gli attacchi MitM.

Se comprendo correttamente il tuo protocollo:

  1. Quando l'applicazione è installata, imposta una chiave segreta per dispositivo che condivide con il server. Non hai detto come - hai intenzione di usare SSL lì?
    Nota che hai bisogno di un segreto condiviso per dispositivo , altrimenti chiunque abbia una copia della tua applicazione può impersonare ogni altro utente dell'applicazione.
  2. Quando l'applicazione client avvia una connessione al server, invia il segreto condiviso al server, crittografato con una chiave pubblica per la quale il server conosce la chiave pubblica. Il server autentica il dispositivo client controllando che il segreto sia quello giusto. Il segreto non è in realtà utilizzato come chiave qui, ma come password.
  3. Il resto della connessione deve essere crittografato e autenticato, altrimenti il MitM può inoltrare i primi pacchetti nella connessione non modificati e snoop o modificare il resto. Hai ancora bisogno di escogitare un protocollo per quella parte. Puoi utilizzare il segreto condiviso come chiave di crittografia e autenticazione (non dimenticare l'autenticazione!).

SSL fa tutto questo meglio.

  1. Non è necessario scambiare le chiavi segrete. Il client verifica che stia parlando con il server previsto verificando il certificato del server: o la chiave pubblica del server è codificata nel pacchetto dell'applicazione (certificato aggiunto), oppure il nome del server è hardcoded nel pacchetto dell'applicazione e nell'applicazione ( tramite le librerie del sistema operativo) verifica che il server presenti un certificato valido che lega la sua chiave pubblica con quel nome.
    Nessun attacco man-in-the-middle è possibile perché il protocollo SSL richiede che il server provi al client che possiede la chiave privata associata al suo certificato. Un MitM non sarebbe in grado di rispondere a questa sfida, quindi il client rileverà l'attacco.
  2. In molti usi di SSL, il server non si cura di quale client si connette ad esso. Se si desidera che il server autentifichi il client, esiste una funzionalità opzionale in SSL per questo: autenticazione client. Genera una coppia di chiavi sul lato client e chiedi di registrare la chiave pubblica sul server.
  3. Il resto della connessione è correttamente crittografato e autenticato. SSL ti offre anche la possibilità di scegliere una suite di cifratura che garantisca la segretezza in avanti (un avversario non sarà in grado di recuperare la chiave di sessione e quindi decrittografare il traffico se compromettono entrambi i partecipanti dopo la sessione è terminata, a un costo leggermente più lento impostazione della connessione).

¹ Per "SSL", intendo una versione non deprecata del protocollo, ovvero TLS 1.0 o superiore. Qualsiasi versione attuale della libreria dovrebbe utilizzare TLS 1.0 o superiore per impostazione predefinita al momento, assicurati di non utilizzarla in una modalità di compatibilità con versioni precedenti SSL ≤3.0.

    
risposta data 21.04.2015 - 01:21
fonte

Leggi altre domande sui tag