android Come evitare il reverse engineering di un file APK?



15 Answers

AFAIK, non è possibile proteggere i file nella directory / res più di quanto non siano protetti in questo momento.

Tuttavia, ci sono dei passi da fare per proteggere il tuo codice sorgente, o almeno quello che fa se non tutto.

  1. Utilizzare strumenti come ProGuard. Questi oscureranno il tuo codice e renderanno più difficile la lettura se decompilato, se non impossibile.
  2. Sposta le parti più critiche del servizio dall'app e in un servizio web, nascosto dietro un linguaggio lato server come PHP. Ad esempio, se hai un algoritmo che ti ha portato via un milione di dollari per scrivere. Ovviamente non vuoi che le persone lo rubino dalla tua app. Spostare l'algoritmo e farlo elaborare i dati su un server remoto e utilizzare l'app per fornire semplicemente i dati. Oppure usa l'NDK per scriverli in modo nativo in file .so, che hanno meno probabilità di essere decompilati rispetto agli apk. Non penso che un decompilatore per i file .so esista anche al momento (e anche se fosse così, non sarebbe buono come i decompilatori Java). Inoltre, come @nikolay menzionato nei commenti, dovresti usare SSL quando interagisci tra il server e il dispositivo.
  3. Quando si memorizzano i valori sul dispositivo, non memorizzarli in un formato non elaborato. Ad esempio, se hai un gioco, e stai memorizzando la quantità di valuta di gioco che l'utente ha in SharedPreferences. Supponiamo che siano 10000 monete. Invece di salvare direttamente 10000 , salvalo usando un algoritmo come ((currency*2)+1)/13 . Quindi, invece di 10000 , si salva 1538.53846154 in SharedPreferences. Tuttavia, l'esempio sopra riportato non è perfetto, e dovrai lavorare per trovare un'equazione che non perderà la valuta per gli errori di arrotondamento, ecc.
  4. Puoi fare una cosa simile per le attività lato server. Ora per un esempio, prendiamo effettivamente la tua app di elaborazione dei pagamenti. Diciamo che l'utente deve effettuare un pagamento di $200 . Invece di inviare un valore $200 non elaborato al server, invia una serie di valori predefiniti più piccoli che sommano fino a $200 . Ad esempio, hai un file o una tabella sul tuo server che equipara parole con valori. Quindi diciamo che Charlie corrisponde a $47 e John a $3 . Quindi, invece di inviare $200 , puoi inviare Charlie quattro volte e John quattro volte. Sul server, interpretare cosa significano e aggiungerlo. Ciò impedisce a un hacker di inviare valori arbitrari al server, poiché non sanno quale parola corrisponde a quale valore. Come misura aggiuntiva di sicurezza, potresti avere un'equazione simile al punto 3 anche per questo, e cambiare le parole chiave ogni n numero di giorni.
  5. Infine, puoi inserire codice sorgente casuale inutile nella tua app, in modo che l'hacker cerchi un ago in un pagliaio. Inserisci classi casuali contenenti snippet da internet o semplicemente funzioni per calcolare cose casuali come la sequenza di Fibonacci. Assicurati che queste classi vengano compilate, ma non utilizzate dalle effettive funzionalità dell'app. Aggiungi abbastanza di queste false classi e l'hacker avrebbe difficoltà a trovare il tuo vero codice.

Tutto sommato, non c'è modo di proteggere la tua app al 100%. Puoi renderlo più difficile, ma non impossibile. Il tuo server web potrebbe essere compromesso, l'hacker potrebbe capire le tue parole chiave monitorando più importi di transazione e le parole chiave che invii per farlo, l'hacker potrebbe scrupolosamente passare attraverso la fonte e capire quale codice è un manichino.

Puoi solo contrattaccare, ma non vincere mai.

android security proguard reverse-engineering

Sto sviluppando un'app di elaborazione dei pagamenti per Android e voglio impedire a un hacker di accedere a risorse, risorse o codice sorgente dal file APK .

Se qualcuno cambia l'estensione .apk in .zip, può decomprimerlo e accedere facilmente a tutte le risorse e le risorse dell'app e, utilizzando dex2jar e un decompilatore Java, può anche accedere al codice sorgente. È molto semplice eseguire il reverse engineering di un file APK Android: per ulteriori dettagli, consultare la sezione . Reverse engineering da un file APK a un progetto .

Ho utilizzato lo strumento Proguard fornito con l'SDK di Android. Quando eseguo il reverse engineering di un file APK generato utilizzando un keystore firmato e Proguard, ottengo codice offuscato.

Tuttavia, i nomi dei componenti Android rimangono invariati e alcuni codici, come i valori-chiave utilizzati nell'app, rimangono invariati. Come da documentazione di Proguard, lo strumento non può offuscare le componenti menzionate nel file Manifest.

Ora le mie domande sono:

  1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?
  2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano in alcun modo compromettere il file APK?
  3. C'è un modo per rendere l'hacking più difficile o addirittura impossibile? Che altro posso fare per proteggere il codice sorgente nel mio file APK?



Prima regola della sicurezza delle app: qualsiasi macchina a cui un utente malintenzionato ottiene accesso fisico o elettronico illimitato ora appartiene al tuo aggressore, indipendentemente da dove sia effettivamente o da cosa hai pagato.

Seconda regola della sicurezza delle app: qualsiasi software che lascia i limiti fisici all'interno dei quali un utente malintenzionato non può penetrare ora appartiene al tuo aggressore, indipendentemente da quanto tempo hai impiegato per codificarlo.

Terza regola: qualsiasi informazione che lascia quegli stessi limiti fisici che un attaccante non può penetrare ora appartiene al tuo aggressore, non importa quanto sia prezioso per te.

Le basi della sicurezza della tecnologia dell'informazione si basano su questi tre principi fondamentali; l'unico computer veramente sicuro è quello bloccato in una cassaforte, all'interno di una gabbia di Farraday, all'interno di una gabbia d'acciaio. Ci sono computer che trascorrono la maggior parte della loro vita di servizio in questo stato; una volta all'anno (o meno), generano le chiavi private per le autorità di certificazione radice attendibili (davanti a una serie di testimoni con telecamere che registrano ogni centimetro della stanza in cui si trovano).

Ora, la maggior parte dei computer non viene utilizzata in questi tipi di ambienti; sono fisicamente fuori all'aperto, connessi a Internet tramite un canale radio wireless. In breve, sono vulnerabili, come lo è il loro software. Quindi non ci si deve fidare di loro. Ci sono alcune cose che i computer e il loro software devono conoscere o fare per essere utili, ma bisogna fare attenzione per assicurarsi che non possano mai sapere o fare abbastanza per causare danni (almeno non danni permanenti al di fuori dei limiti di quella singola macchina ).

Sapevi già tutto questo; è per questo che stai cercando di proteggere il codice della tua applicazione. Ma qui sta il primo problema; gli strumenti di offuscamento possono rendere il codice un pasticcio per un umano per cercare di scavare, ma il programma deve ancora funzionare; ciò significa che il flusso logico effettivo dell'app e i dati che utilizza non sono influenzati dall'offuscamento. Data una certa tenacia, un utente malintenzionato può semplicemente non-offuscare il codice, e ciò non è nemmeno necessario in alcuni casi in cui ciò che sta guardando non può essere nient'altro che ciò che sta cercando.

Invece, dovresti cercare di assicurarti che un intruso non possa fare nulla con il tuo codice, non importa quanto sia facile per lui ottenerne una copia chiara. Ciò significa che non ci sono segreti codificati, perché quei segreti non sono segreti non appena il codice lascia l'edificio in cui lo hai sviluppato.

Questi valori-chiave che hai hard-coded dovrebbero essere completamente rimossi dal codice sorgente dell'applicazione. Invece, dovrebbero essere in uno dei tre posti; memoria volatile sul dispositivo, che è più difficile (ma non impossibile) per un utente malintenzionato per ottenere una copia offline di; permanentemente sul cluster di server, al quale si controlla l'accesso con un pugno di ferro; o in un secondo archivio dati non correlato al tuo dispositivo o server, come una scheda fisica o nei ricordi dell'utente (il che significa che alla fine sarà nella memoria volatile, ma non deve essere per molto tempo).

Considera lo schema seguente. L'utente inserisce le proprie credenziali per l'app dalla memoria nel dispositivo. Sfortunatamente, devi fidarti che il dispositivo dell'utente non è già stato compromesso da un keylogger o da un Trojan; il meglio che puoi fare a questo riguardo è implementare la sicurezza multi-fattore, ricordando le informazioni di identificazione difficili da falsi sui dispositivi che l'utente ha utilizzato (MAC / IP, IMEI, ecc.) e fornendo almeno un canale aggiuntivo da che può essere verificato un tentativo di accesso su un dispositivo sconosciuto.

Le credenziali, una volta inserite, vengono offuscate dal software client (utilizzando un hash sicuro) e le credenziali di testo semplice vengono scartate; hanno servito il loro scopo. Le credenziali offuscate vengono inviate su un canale protetto al server autenticato dal certificato, che le blocca nuovamente per produrre i dati utilizzati per verificare la validità del login. In questo modo, il client non sa mai cosa sia effettivamente confrontato con il valore del database, il server dell'app non conosce mai le credenziali in chiaro dietro ciò che riceve per la convalida, il server dati non sa mai come vengono prodotti i dati memorizzati per la convalida e un uomo in il mezzo vede solo parole senza senso anche se il canale sicuro è stato compromesso.

Una volta verificato, il server trasmette un token sul canale. Il token è utile solo all'interno della sessione protetta, è composto da rumore casuale o una copia crittografata (e quindi verificabile) degli identificativi di sessione, e l'applicazione client deve inviare questo token sullo stesso canale al server come parte di qualsiasi richiesta fare qualcosa. L'applicazione client lo farà molte volte, perché non può fare nulla che coinvolga denaro, dati sensibili o qualsiasi altra cosa che potrebbe essere dannosa di per sé; deve invece chiedere al server di fare questo compito. L'applicazione client non scriverà mai alcuna informazione sensibile alla memoria persistente sul dispositivo stesso, almeno non in testo normale; il client può chiedere al server tramite il canale sicuro una chiave simmetrica per crittografare tutti i dati locali, che il server ricorderà; in una sessione successiva il client può chiedere al server la stessa chiave per decrittografare i dati da utilizzare nella memoria volatile. Anche quei dati non saranno l'unica copia; tutto ciò che i negozi client dovrebbero anche essere trasmessi in qualche forma al server.

Ovviamente, ciò rende la tua applicazione fortemente dipendente dall'accesso a Internet; il dispositivo client non può eseguire nessuna delle sue funzioni di base senza una corretta connessione e autenticazione da parte del server. Non diverso da Facebook, davvero.

Ora, il computer che l'utente malintenzionato vuole è il tuo server, perché esso e non l'app / dispositivo client è la cosa che può fargli guadagnare denaro o causare dolore agli altri per il suo divertimento. Va bene; ottieni molto più denaro per la tua spesa e spendi denaro per proteggere il server piuttosto che cercare di proteggere tutti i clienti. Il server può essere protetto da tutti i tipi di firewall e altri dispositivi di sicurezza elettronici e può inoltre essere fisicamente protetto dietro l'acciaio, il cemento, l'accesso con chiave magnetica / pin e la videosorveglianza 24 ore su 24. Il tuo aggressore dovrebbe essere davvero molto sofisticato per ottenere qualsiasi tipo di accesso al server direttamente, e tu dovresti (dovresti) sapere immediatamente.

Il meglio che un aggressore può fare è rubare il telefono e le credenziali di un utente e accedere al server con i diritti limitati del client. Se ciò dovesse accadere, proprio come perdere una carta di credito, l'utente legittimo dovrebbe essere istruito a chiamare un numero di 800 (preferibilmente facile da ricordare, e non sul retro di una carta che porterebbe nella loro borsa, portafoglio o valigetta che potrebbe essere rubato insieme al dispositivo mobile) da qualsiasi telefono a cui possano accedere che li colleghi direttamente al servizio clienti. Dichiarano che il loro telefono è stato rubato, forniscono un identificatore univoco di base e l'account è bloccato, tutte le transazioni che l'autore dell'attacco potrebbe essere stato in grado di eseguire il rollback e l'attaccante è tornato al punto di partenza.




Il 100% di evitare il reverse engineering dell'APK Android non è possibile, ma puoi utilizzare questi modi per evitare di estrarre più dati, come il codice sorgente, le risorse del tuo APK e le risorse:

  1. Utilizzare ProGuard per offuscare il codice dell'applicazione

  2. Usa NDK usando C e C ++ per mettere il core dell'applicazione e parte sicura del codice nei file .so

  3. Per proteggere le risorse, non includere tutte le risorse importanti nella cartella delle risorse con APK. Scarica queste risorse al momento dell'applicazione per la prima volta.




1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?

Questo è impossibile

2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano in alcun modo compromettere il file APK?

Gli sviluppatori possono prendere provvedimenti come usare strumenti come ProGuard per offuscare il loro codice, ma fino ad ora, è stato abbastanza difficile impedire completamente a qualcuno di decompilare un'app.

È uno strumento davvero eccezionale e può aumentare la difficoltà di "invertire" il codice riducendo al contempo l'ingombro del codice.

Supporto ProGuard integrato: ProGuard è ora fornito con gli strumenti SDK. Gli sviluppatori possono ora offuscare il loro codice come parte integrata di una build di rilascio.

3. C'è un modo per rendere l'hacking più difficile o addirittura impossibile? Che altro posso fare per proteggere il codice sorgente nel mio file APK?

Durante la ricerca, sono venuto a conoscenza di HoseDex2Jar . Questo strumento proteggerà il tuo codice dalla decompilazione, ma sembra che non sia possibile proteggere completamente il tuo codice.

Alcuni link utili, puoi fare riferimento a loro.




Ecco alcuni metodi che puoi provare:

  1. Utilizzare l' obfuscation e strumenti come ProGuard .
  2. Cripta parte della fonte e dei dati.
  3. Utilizzare un checksum incorporato e proprietario nell'app per rilevare la manomissione.
  4. Introdurre il codice per evitare il caricamento in un debugger, ovvero consentire all'app di rilevare il debugger e uscire / chiudere il debugger.
  5. Separare l'autenticazione come servizio online.
  6. Usa la diversità delle applicazioni
  7. Prima di autenticare il dispositivo, utilizzare la tecnica di stampa con le dita, ad esempio, le firme hardware dei dispositivi provenienti da diversi sottosistemi.



Il tuo cliente dovrebbe assumere qualcuno che sappia cosa sta facendo, chi può prendere le decisioni giuste e può aiutarti.

Parlare sopra di te che hai qualche possibilità di cambiare il sistema di elaborazione delle transazioni sul back-end è assurdo - non ti dovrebbe essere permesso di apportare tali modifiche architettoniche, quindi non aspettarti di essere in grado di farlo.

La mia motivazione su questo:

Poiché il tuo dominio è l'elaborazione dei pagamenti, è sicuro assumere che PCI DSS e / o PA DSS (e le potenziali leggi statali / federali) saranno importanti per la tua attività: per essere conforme devi dimostrare di essere sicuro. Per non essere sicuro, scoprire (tramite test) che non si è sicuri, quindi correggere, ripetere il test, ecc. Finché la sicurezza non può essere verificata ad un livello adeguato = modo costoso, lento, ad alto rischio per il successo. Per fare la cosa giusta, pensare bene, impegnare il talento esperto nel lavoro, sviluppare in modo sicuro, quindi testare, correggere (meno), eccetera (meno) fino a quando la sicurezza può essere verificata ad un livello adeguato = economico, veloce, modo a basso rischio per il successo.




Se vogliamo rendere il reverse engineering (quasi) impossibile, possiamo mettere l'applicazione su un chip altamente resistente alla manomissione, che esegue internamente tutte le cose sensibili, e comunica con alcuni protocolli per rendere possibile la GUI di controllo sull'host. Anche i chip resistenti alle manomissioni non sono al 100% resistenti alle crepe; hanno appena impostato la barra molto più in alto rispetto ai metodi software. Ovviamente, questo è scomodo: l'applicazione richiede una piccola verruca USB che trattiene il chip da inserire nel dispositivo.

La domanda non rivela la motivazione per voler proteggere questa applicazione così gelosamente.

Se l'obiettivo è migliorare la sicurezza del metodo di pagamento nascondendo qualsiasi difetto di sicurezza che l'applicazione possa avere (conosciuto o meno), è completamente sbagliato. I bit sensibili alla sicurezza dovrebbero in effetti essere open source, se ciò è fattibile. Dovresti renderlo il più semplice possibile per qualsiasi ricercatore della sicurezza che riveda la tua domanda per trovare quei pezzi e controllare il loro funzionamento e per contattarti. Le domande di pagamento non devono contenere certificati incorporati. Vale a dire, non ci dovrebbe essere alcuna applicazione server che si fida di un dispositivo semplicemente perché ha un certificato fisso dalla fabbrica. Una transazione di pagamento dovrebbe essere effettuata solo sulle credenziali dell'utente, utilizzando un protocollo di autenticazione end-to-end progettato correttamente che preclude la fiducia nell'applicazione, o la piattaforma, o la rete, ecc.

Se l'obiettivo è impedire la clonazione, a meno di quel chip a prova di manomissione, non c'è nulla che tu possa fare per proteggere il programma da essere decodificato e copiato, in modo che qualcuno incorpori un metodo di pagamento compatibile nella propria applicazione, dando salire a "clienti non autorizzati". Ci sono modi per rendere difficile lo sviluppo di client non autorizzati. Uno sarebbe quello di creare checksum basati su istantanee dello stato completo del programma: tutte le variabili di stato, per tutto. GUI, logica, qualunque cosa. Un programma clone non avrà esattamente lo stesso stato interno. Certo, è una macchina a stati che ha simili transizioni di stato visibili esternamente (come può essere osservato da ingressi e uscite), ma difficilmente lo stesso stato interno. Un'applicazione server può interrogare il programma: qual è il tuo stato dettagliato? (cioè dammi un checksum su tutte le tue variabili di stato interne). Questo può essere confrontato con il codice client fittizio che viene eseguito sul server in parallelo, passando attraverso le transizioni di stato originali. Un clone di terze parti dovrà replicare tutti i cambiamenti di stato rilevanti del programma originale al fine di dare le risposte corrette, il che ostacolerà il suo sviluppo.







Fondamentalmente non è possibile. Non sarà mai possibile. Tuttavia, c'è speranza. Puoi usare un obfuscation per renderlo così che alcuni attacchi comuni sono molto più difficili da eseguire, inclusi cose come:

  1. Rinominare metodi / classi (quindi nel decompilatore si ottengono tipi come aa)
  2. Offuscamento del flusso di controllo (quindi nel decompilatore il codice è molto difficile da leggere)
  3. Crittografia delle stringhe e possibilmente delle risorse

Sono sicuro che ce ne sono altri, ma quelli sono i principali. Lavoro per un'azienda denominata PreEmptive Solutions su un obfuscator .NET . Hanno anche un obfuscator Java che funziona per Android e uno chiamato DashO .

L'offuscamento porta sempre con sé un prezzo. In particolare, le prestazioni sono in genere peggiori e richiede di solito un po 'di tempo in più per le uscite. Tuttavia, se la tua proprietà intellettuale è estremamente importante per te, allora di solito ne vale la pena.

Altrimenti, la tua unica scelta è di fare in modo che la tua applicazione Android passi semplicemente attraverso un server che ospita tutta la vera logica della tua applicazione. Questo ha la sua parte di problemi, perché significa che gli utenti devono essere connessi a Internet per utilizzare la tua app.

Inoltre, non è solo Android che ha questo problema. È un problema in ogni app store. È solo questione di quanto sia difficile arrivare al file del pacchetto (ad esempio, non credo che sia molto semplice su iPhone, ma è ancora possibile).




Non c'è modo di evitare completamente il reverse engineering di un APK. Per proteggere le risorse delle applicazioni e le risorse, è possibile utilizzare la crittografia.

  • La crittografia renderà più difficile l'utilizzo senza decrittografia. L'eliminazione di alcuni algoritmi di crittografia intensi renderà più difficile l'esecuzione di crack.
  • Aggiungendo un codice spoof nella tua logica principale per rendere più difficile il cracking.
  • Se riesci a scrivere la tua logica critica in qualsiasi lingua nativa e questo sicuramente renderà più difficile la decompilazione.
  • Utilizzare qualsiasi framework di sicurezza di terze parti come Quixxi



I chip TPM (Trusted Platform Module) non sono progettati per gestire il codice protetto? Stanno diventando comuni sui PC (specialmente quelli Apple) e potrebbero già esistere nei chip degli smartphone di oggi. Sfortunatamente non ci sono API OS per utilizzarlo ancora. Speriamo che Android aggiungerà il supporto per questo giorno. Questa è anche la chiave per pulire i contenuti DRM (su cui Google sta lavorando per WebM).




Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano in alcun modo compromettere il file APK?

Un file APK è protetto con l' algoritmo SHA . Puoi vedere alcuni file nella cartella META-INF dell'APK. Se si estrae un file APK e si modifica qualsiasi contenuto e lo si comprime nuovamente e quando si esegue quel nuovo file APK su un computer Android, non funzionerà, poiché gli hash SHA-1 non corrisponderanno mai.




Se la tua app è così sensibile, dovresti considerare la parte di elaborazione dei pagamenti sul lato server. Prova a modificare gli algoritmi di elaborazione dei pagamenti. Utilizza l'app Android solo per raccogliere e visualizzare le informazioni dell'utente (ad esempio il saldo del conto) e invece di elaborare i pagamenti all'interno dei codici java, invia questa attività al tuo server utilizzando un protocollo SSL sicuro con parametri crittografati. Crea API completamente crittografate e sicure per comunicare con il tuo server.

Ovviamente, può anche essere hackerato e non ha nulla a che fare con la protezione dei codici sorgente, ma consideralo un altro livello di sicurezza per rendere più difficile agli hacker ingannare la tua app.




Strumento: l'utilizzo di Proguard nella tua applicazione può essere limitato alla decodificazione della tua applicazione




Solo un'aggiunta alle già buone risposte sopra.

Un altro trucco che so è quello di memorizzare codici preziosi come libreria Java. Quindi imposta quella libreria come il tuo progetto Android. Sarebbe buono come file .so, ma Android Lib avrebbe fatto.

In questo modo questi preziosi codici memorizzati nella Libreria Android non saranno visibili dopo la decompilazione.






Related