How to harden an iPhone/Android app so its tough to reverse-engineer it?
Prevenire il reverse engineering del software è un problema difficile.
Prevenire il reverse engineering del software applicativo su una piattaforma informatica generica con assistenza hardware debole (PC, iPhone o telefono Android) per un periodo di tempo significativo (mesi) è un problema eccezionalmente difficile.
Generalmente invece di proteggere l'intera applicazione un'alternativa comune consiste nel tentare di proteggere i dati critici utilizzati dall'applicazione e rinunciare a proteggere l'intera applicazione.
[1] Make the app hard to crack, as the binary will hold some secret tokens.
Il tuo però qui espone il concetto di 'proteggere i dati'. Quello che vuoi veramente che l'applicazione protegga sono alcuni pezzi di dati critici: i token segreti.
Come proteggi i dati quando l'applicazione non è in grado di proteggersi?
Passa la responsabilità al sistema operativo. Esistono due tipi di protezione che i sistemi operativi possono offrire: controllo dell'accesso e crittografia. La maggior parte delle protezioni che utilizziamo quando consentiamo o neghiamo la lettura di dati o l'esecuzione di un'azione specifica sono i controlli di accesso.
Un controllo di accesso assume come input un'azione e un identificatore di chi vuole eseguire l'azione. Il suo output può approvare o negare il permesso di eseguire l'azione. Un controllo di accesso utilizza un set o regole o una tabella per determinare se un identificatore deve essere autorizzato a eseguire un'azione.
Ad esempio: Alice ha un gioco FunGame su un computer. Il controllo degli accessi del computer ha una regola che solo Alice può eseguire FunGame. Bob si siede al computer e tenta di eseguire FunGame. Il controllo degli accessi del computer prende come input 'run FunGame' e 'Bob'. In base alla regola 'solo Alice può eseguire FunGame' l'output del controllo di accesso è negato.
Il controllo degli accessi fornisce un modo diretto e generale per prendere decisioni su consentire o negare, mentre la crittografia fornisce un metodo più indiretto di consentire o negare. Con la crittografia e la decifratura possiamo trasformare i dati in modo che i dati abbiano senso o non abbiano senso.
La crittografia e la decrittografia richiedono almeno una chiave crittografica. Il valore della chiave diventa un controllo di accesso con le due regole 'consentire a chiunque abbia la chiave di prendere dati comprensibili e renderlo incomprensibile' e 'consentire a chiunque abbia la chiave di prendere dati incomprensibili e renderli comprensibili'. Rendere incomprensibili i dati protegge solo i dati da comprendere. Un individuo può ancora essere in grado di leggere i dati, ma non sarà in una forma che comprendono.
Si noti che la chiave anziché l'identificatore di un attore diventa il componente critico. Chiunque abbia la chiave, indipendentemente dal modo in cui lo ottiene, può accedere ai dati. Ciò rende la memorizzazione della chiave un problema. Se memorizzi la chiave sullo stesso sistema dei dati che stai fornendo a chiunque con i mezzi per accedere ai tuoi dati. Questo è il motivo per cui le passphrase richiedono la memorizzazione. Memorizzando una passphrase memorizza la chiave (passphrase) nella tua testa invece che nel sistema.
Quindi, per proteggere i token puoi usare i controlli di accesso del sistema operativo, oppure puoi crittografare i token, o entrambi. Se qualcuno ha un sistema operativo che non impone i propri controlli di accesso (iPhone jailbroken o telefono Android rooted), non è possibile fare affidamento sui controlli di accesso del sistema operativo. Tuttavia, finché la chiave utilizzata per crittografare i token non risiede nello stesso sistema dei token crittografati, i token saranno comunque protetti anche se il sistema operativo è compromesso.
Tuttavia, tenere la chiave fuori dal sistema in questione è un altro problema difficile chiamato gestione delle chiavi.
[2] If it still can be cracked, is there any way the app can tell someone or its own self that it has been cracked(like checking against some checksum or certificate or the OS doing it for the app) and take some action?
The app binary can get infected or bad code can get injected while the program is in memory as well, so suggested methods should be able to deal with both these cases
Il concetto di esaminare un pezzo di dati per vedere se è inalterato dall'ultima ispezione è chiamato controllo dell'integrità. Un modo efficace per valutare lo stato di una porzione di dati è chiamato hashing crittografico. Per eseguire il controllo dell'integrità, è necessario innanzitutto calcolare l'hash crittografico di un pezzo di dati e quindi proteggere il valore hash risultante. In un secondo momento ricalcolare l'hash crittografico sullo stesso pezzo di dati. Confrontare il valore hash ricalcolato con il valore hash protetto. Se i due valori sono identici, i dati non vengono modificati. Se i due valori di hash sono diversi, i dati sono stati modificati.
È possibile trattare il binario dell'applicazione in memoria come parte di dati ed eseguirne il controllo di integrità. Si può anche trattare il binario dell'applicazione in memoria come un pezzo di dati ed eseguire il controllo di integrità su di esso.
Il concetto di esaminare un programma in esecuzione per vedere se sta elaborando come progettato è chiamato attestazione. Il controllo di tutta la memoria utilizzata dal codice in esecuzione è tipicamente impossibile, quindi l'attestazione di solito verifica qualcosa di più semplice, come i valori di alcuni set di dati o lo stato del programma in esecuzione e la sua transizione tra stati. L'attestato è difficile da raggiungere, quindi non è ampiamente utilizzato nel software commerciale.