2012-02-07 3 views
7

Sto sviluppando un'applicazione per Android e devo mantenere una comunicazione sicura con un server attraverso una coppia di chiave privata e pubblica. Qual è il modo più sicuro per memorizzare la chiave privata nel mio apk? Ovviamente ho intenzione di offuscare il codice ma voglio più sicurezza. Ho pensato la seguente opzione:che è il modo più sicuro per includere una coppia di chiavi (pubblica/privata) in un apk

Se creo una libreria di condivisione nativa con i metodi per firmare le informazioni di transazione, l'apk deve solo contenere il file .so e questo file è in codice macchina, quindi la decompilazione potrebbe essere difficile, non è vero?

qualche idea? Grazie

+0

Chi è l'autore dell'attacco nel modello di minaccia? L'utente legittimo del tuo dispositivo? – CodesInChaos

+0

L'utente malintenzionato non sarà l'utente, il problema è che l'app accederà a un servizio di pagamento e vogliamo un'app sicura. In un semplice apk chiunque può decompilare, ottenere le chiavi e usarle per accedere al sistema di pagamento – rdiaz82

+2

Si dovrebbe progettare l'applicazione in modo che un utente che ha il codice sorgente completo dell'applicazione e tutte le chiavi incorporate non possa fare nulla il male. – CodesInChaos

risposta

2

Prima di tutto, per implementare comunicazioni sicure tra l'applicazione client e un server, concettualmente, è necessaria solo la chiave pubblica del server. Ciò consente di stabilire una relazione di fiducia unidirezionale con il server e di stabilire una sessione sicura, in cui è garantita l'identità del server.

Mentre il metodo precedente non fornisce un trust bidirezionale (il client non può essere identificato sul server), quando si stabilisce il canale di comunicazione nella maggior parte delle applicazioni, questo livello di affidabilità non è realmente richiesto.

Se i requisiti per fornire l'autenticazione del client al server utilizzando chiavi pubbliche/private, le cose diventano più complicate perché se inserisci la chiave nell'apk, non importa quanto lo offuscate (inclusa l'incorporamento in una libreria nativa) rallenterà solo un utente nefasto dedicato.

L'unico modo per conservare la chiave privata con il cliente è per crittografare esso. Ma poi hai un problema simile a dove memorizzare la chiave di decrittografia. La soluzione più semplice è generare una coppia di chiavi pubblica/privata per l'utente dell'applicazione client e chiedere all'utente di fornire una chiave di crittografia/decrittografia simmetrica (che l'utente dovrà sempre digitare) per decrittografare la chiave privata ogni volta che l'utente sta usando l'applicazione.

L'alternativa sarebbe utilizzare una sorta di dispositivo hardware crittografico dedicato simile a una smart card che memorizzerebbe la chiave privata in modo sicuro ma si ha ancora il problema di autorizzare l'applicazione a leggere la chiave dal dispositivo (per non parlare la complicazione dell'interfacciamento con detto dispositivo).

Ora, la domanda che devi porsi è questa: "Chi stai cercando di impedire di leggere la chiave privata?" (ovviamente dopo aver risposto l'altra domanda: "Hai veramente bisogno/privato coppia di chiavi pubblica una per il cliente").

+0

La chiave pubblica/privata lato client è forzata dal lato server. Devo calcolare l'hash dei dati, quindi codificare l'hash con la chiave privata e inviare i miei dati, il risultato dell'hash e la chiave pubblica al server. Questo è il mio problema principale, come posso proteggere la chiave privata !! :) – rdiaz82

+0

@ rdiaz82, in questo caso è molto probabile che generi una nuova chiave pubblica/privata per la sessione. In questo modo la chiave privata viene generata in fase di esecuzione e riciclata per ogni sessione. Questo a meno che il server non abbia in qualche modo bisogno di una copia della chiave pubblica del client per essere registrata in anticipo. –

+1

La chiave privata in uno scenario di questo tipo è solitamente quella generata per identificare l'utente dell'app, non la stessa chiave pubblica utilizzata per crittografare le risposte al server. In questo caso, la chiave deve essere memorizzata sul dispositivo dopo la generazione in quanto è la chiave dell'utente. – mikebabcock

4

Conservare la coppia di chiavi in ​​un chiavi e include il keystore come risorsa nel vostro APK. Android tende a preferire la (BKS) formato BouncyCastle archivio chiavi. I keystore sono progettati appositamente per questo scopo.

Si noti che è necessario proteggere il keystore con una password e l'applicazione dovrà conoscere tale password per accedere al keystore. Quindi, ti rimane la necessità di chiedere all'utente una password per accedere al keystore o includere la password nel tuo codice (offuscarla per rendere più difficile a un utente malintenzionato il retroingegnerizzazione). Se qualcuno sta affrontando il problema del reverse engineering dell'applicazione per ripristinare il keystore crittografato e la password necessaria per accedervi, inclusa la password in una libreria nativa compilata non presenterà un ostacolo aggiuntivo.

Tuttavia, potrebbe non essere necessario per farlo in ogni caso.Se il tuo obiettivo è proteggere/crittografare i dati nel trasporto da/verso il server, usa SSL/TLS. Se non stai facendo l'autenticazione lato client, il tuo server ha bisogno di un certificato SSL ma il tuo client no; il protocollo si occupa di generare le chiavi di crittografia in modo sicuro. Se vuoi che il server autentifichi il client (fai in modo che il tuo server parli solo con i tuoi clienti), devi installare un certificato SSL sul lato client con la tua app ... questa è la chiave privata che stai probabilmente a pensare.

Ti indicherò anche a Application Security for the Android Platform. Questo libro (disclaimer: ho scritto il libro) ha un intero capitolo che parla di come progettare comunicazioni Android app-to-server sicure, con esempi di codice per illustrare come implementare le protezioni appropriate. Puoi dargli una lettura.

+0

La tua risposta ha aperto diversi modi per risolvere il problema. Nonostante l'offuscamento, penso che la password per il keystore sia ancora visibile nel codice, quindi non è difficile ottenere l'accesso al keystore. – rdiaz82

+0

È vero. Comunque ... questo è il meglio che c'è. Se l'app client in esecuzione sul dispositivo richiede l'accesso a qualcosa che viene archiviata, anche una persona con accesso a tale dispositivo potrà accedervi. Tutto ciò che puoi fare lo rende più difficile. Naturalmente, non è possibile memorizzare la password e costringere l'utente a digitarlo ogni volta che è necessario accedere alle chiavi. Non un UX ideale, ma quella password deve venire da qualche parte. – jeffsix

+0

Questo è un grosso problema! Devo proteggere il certificato del lato client. L'app è per l'acquisto e tutte le transazioni tra il client (chiunque usi l'app) e il server devono essere firmate. Ho paura che chiunque possa estrarre il certificato e iniziare a inviare transazioni valide al server. – rdiaz82

Problemi correlati