Comment éviter l'ingénierie inverse d'un fichier APK?


764

Je développe une application de traitement des paiements pour Android et je souhaite empêcher un pirate d'accéder à des ressources, des actifs ou du code source à partir du fichier APK .

Si quelqu'un modifie l'extension .apk en .zip, il peut la décompresser et accéder facilement à toutes les ressources et ressources de l'application, et en utilisant dex2jar et un décompilateur Java, il peut également accéder au code source. Il est très facile de procéder à une rétro-ingénierie d'un fichier APK Android - pour plus de détails, consultez la question Stack Overflow Reverse engineering d'un fichier APK vers un projet .

J'ai utilisé l'outil Proguard fourni avec le SDK Android. Lorsque j'effectue le reverse engineering d'un fichier APK généré à l'aide d'un magasin de clés signé et de Proguard, j'obtiens du code obscurci.

Cependant, les noms des composants Android restent inchangés et certains codes, comme les valeurs-clés utilisées dans l'application, restent inchangés. Selon la documentation de Proguard, l'outil ne peut pas masquer les composants mentionnés dans le fichier manifeste.

Maintenant mes questions sont:

  1. Comment puis-je empêcher complètement l'ingénierie inverse d'un APK Android? Est-ce possible?
  2. Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?
  3. Existe-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source de mon fichier APK?

120
Il semble que vous utilisiez la «sécurité par l'obscurité» si votre schéma de traitement des paiements repose sur le fonctionnement du client qui reste secret.
PeterJ

43
Avez-vous envisagé d'écrire les parties importantes du code en C / C ++ et de les ajouter en tant que bibliothèque compilée? Ils peuvent être désassemblés en code assembleur, mais la rétro-ingénierie d'une grande bibliothèque d'assemblage est extrêmement chronophage.
Leo


60
Bienvenue sur la question fondamentale de la création de tout actif numérique. Les pirates peuvent descendre au niveau des instructions de la machine, donc si un ordinateur peut lire le fichier, il peut être piraté / copié, aucune obfuscation ou DRM ne peut jamais complètement arrêter un pirate déterminé. Si vous avez besoin de sécurité, assurez-vous que les clés privées ne sont jamais dans la source et sachez au stade de la conception que seule l'isolement (matériel distant et / ou dédié) peut les protéger.
Keith

16
Notez que selon ce que fait votre application de traitement des paiements, il peut y avoir une politique réglementaire et juridique qui affecte votre application et pourrait potentiellement vous exposer à des sanctions sévères: voir la conformité PCI, en commençant par pcicomplianceguide.org/pcifaqs.php#11 .
bloopletech

Réponses:


372

 1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

AFAIK, il n'y a aucune astuce pour éviter complètement l'ingénierie inverse.

Et aussi très bien dit par @inazaruk: quoi que vous fassiez à votre code, un attaquant potentiel est en mesure de le modifier de quelque manière qu'il ou elle le trouve réalisable . Vous ne pouvez pas protéger votre application contre toute modification. Et toute protection que vous y mettez peut être désactivée / supprimée.

 2. Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?

Vous pouvez cependant faire différentes astuces pour rendre le piratage plus difficile. Par exemple, utilisez l'obfuscation (s'il s'agit de code Java). Cela ralentit généralement considérablement l'ingénierie inverse.

 3. Existe-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source de mon fichier APK?

Comme tout le monde le dit, et comme vous le savez probablement, il n'y a pas de sécurité à 100%. Mais le point de départ pour Android, que Google a intégré, est ProGuard. Si vous avez la possibilité d'inclure des bibliothèques partagées , vous pouvez inclure le code nécessaire en C ++ pour vérifier la taille des fichiers, l'intégration, etc. Si vous devez ajouter une bibliothèque native externe au dossier de bibliothèque de votre APK sur chaque build, vous pouvez l'utiliser par la suggestion ci-dessous.

Placez la bibliothèque dans le chemin de bibliothèque natif qui est par défaut "libs" dans votre dossier de projet. Si vous avez construit le code natif de la cible 'armeabi', placez-le sous libs / armeabi . S'il a été construit avec armeabi-v7a, mettez-le sous libs / armeabi-v7a.

<project>/libs/armeabi/libstuff.so

1
Pour la transaction de paiement, j'ai utilisé la norme ISO 8585, en ce moment le schéma de cette norme est en paire clé-valeur en utilisant la collection HashMap de Java et quand je fais de l'ingénierie inverse sur apk, j'obtiendrai tout le schéma. exposé via l'ingénierie inverse.? Votre dernière suggestion de bibliothèques de partage peut-elle être utile dans ce cas? Doy, vous avez des liens pour que je puisse obtenir une exposition aux bibliothèques de partage dans Android.
sachin003

4
que diriez-vous de chiffrer vos chaînes dans le code et de les déchiffrer au moment de l'exécution? Si vous effectuez le déchiffrement sur un serveur distant, comme d'autres personnes l'ont suggéré, vous n'avez pas le problème que la clé de déchiffrement se trouve dans les sources.
kutschkem

oui, le cryptage est un moyen, mais il n'est pas sûr de ne pas être piraté. Si je crypte la chaîne afin de les décrypter, j'ai besoin d'un identifiant unique dans le code. et si quelqu'un est capable de le décompiler, il sera très facile d'obtenir l'identifiant unique.
Bhavesh Patadiya

pourquoi vous avez ajouté Edité genre de choses? son tout régulier.
Mohammed Azharuddin Shaikh

@hotveryspicy: oui, j'ai maintenant supprimé la marque "édité" de answer.j'ai édité ma réponse car il voulait en savoir plus sur la façon dont les bibliothèques de partage sont utiles dans ce cas.
Bhavesh Patadiya

126

AFAIK, vous ne pouvez plus protéger les fichiers du répertoire / res qu'ils ne le sont actuellement.

Cependant, il existe des mesures que vous pouvez prendre pour protéger votre code source, ou du moins ce qu'il fait sinon tout.

  1. Utilisez des outils comme ProGuard. Ceux-ci obscurciront votre code et le rendront plus difficile à lire une fois décompilé, voire impossible.
  2. Déplacez les parties les plus critiques du service hors de l'application et dans un service Web, caché derrière un langage côté serveur comme PHP. Par exemple, si vous avez un algorithme qui vous a pris un million de dollars à écrire. Vous ne voulez évidemment pas que les gens le volent dans votre application. Déplacez l'algorithme et demandez-lui de traiter les données sur un serveur distant, et utilisez l'application pour lui fournir simplement les données. Ou utilisez le NDK pour les écrire nativement dans des fichiers .so, qui sont beaucoup moins susceptibles d'être décompilés que les apks. Je ne pense pas qu'un décompilateur pour les fichiers .so existe déjà (et même s'il le faisait, il ne serait pas aussi bon que les décompilateurs Java). De plus, comme @nikolay l'a mentionné dans les commentaires, vous devez utiliser SSL lors de l'interaction entre le serveur et l'appareil.
  3. Lorsque vous stockez des valeurs sur l'appareil, ne les stockez pas dans un format brut. Par exemple, si vous avez un jeu et que vous stockez le montant de la devise de jeu de l'utilisateur dans SharedPreferences. Supposons que ce soient des 10000pièces. Au lieu d'enregistrer 10000directement, enregistrez-le en utilisant un algorithme comme ((currency*2)+1)/13. Donc, au lieu de 10000, vous enregistrez 1538.53846154dans les SharedPreferences. Cependant, l'exemple ci-dessus n'est pas parfait, et vous devrez travailler pour trouver une équation qui ne perdra pas de la monnaie en raison des erreurs d'arrondi, etc.
  4. Vous pouvez faire la même chose pour les tâches côté serveur. Maintenant, pour un exemple, prenons en fait votre application de traitement des paiements. Disons que l'utilisateur doit effectuer un paiement de $200. Au lieu d'envoyer une $200valeur brute au serveur, envoyez une série de valeurs prédéfinies plus petites qui s'additionnent $200. Par exemple, disposez d'un fichier ou d'une table sur votre serveur qui associe les mots aux valeurs. Disons que cela Charliecorrespond à $47, et Johnà $3. Ainsi, au lieu d'envoyer $200, vous pouvez envoyer Charliequatre fois etJohnquatre fois. Sur le serveur, interprétez leur signification et ajoutez-les. Cela empêche un pirate d'envoyer des valeurs arbitraires à votre serveur, car il ne sait pas quel mot correspond à quelle valeur. Comme mesure de sécurité supplémentaire, vous pouvez également avoir une équation similaire au point 3 et modifier les mots clés tous les njours.
  5. Enfin, vous pouvez insérer du code source aléatoire aléatoire dans votre application, afin que le pirate recherche une aiguille dans une botte de foin. Insérez des classes aléatoires contenant des extraits d'Internet, ou simplement des fonctions pour calculer des choses aléatoires comme la séquence de Fibonacci. Assurez-vous que ces classes sont compilées, mais ne sont pas utilisées par les fonctionnalités réelles de l'application. Ajoutez suffisamment de ces fausses classes, et le pirate aurait du mal à trouver votre vrai code.

Dans l'ensemble, il n'y a aucun moyen de protéger votre application à 100%. Vous pouvez le rendre plus difficile, mais pas impossible. Votre serveur Web pourrait être compromis, le pirate pourrait comprendre vos mots-clés en surveillant plusieurs montants de transaction et les mots-clés que vous envoyez, le pirate pourrait minutieusement parcourir la source et déterminer quel code est un mannequin.

Vous ne pouvez que riposter, mais jamais gagner.


136
Au lieu de faire des tours avec des valeurs que vous envoyez à votre serveur, utilisez SSL et validez correctement le certificat de serveur. La sécurité par obscurité est généralement une mauvaise idée.
Nikolay Elenkov

48
vous pouvez insérer du code source inutile et aléatoire dans votre application . Cela ne peut pas vraiment aider non plus. Cela ne fera que gonfler votre application, tout en la rendant plus difficile à maintenir également.
Anirudh Ramanathan

4
Vous pouvez également simuler l'utilisation du code inutile et envoyer les données au serveur qui les supprimera. Une fausse sécurité peut-être, mais une douleur dans le cul pour le pirate potentiel, non?
Benoit Duffez

19
Si votre algorithme vaut un million de dollars, ce n'est pas parce qu'il n'y a pas de décompilateur pour les .sofichiers que je ne peux pas lire l'assembly :) La plupart d'entre eux tombent dans le même piège, simplement obscurcissant au lieu de vous protéger correctement. L'obfuscation ne fonctionne que si cela ne vaut pas le temps d'un attaquant de suivre, donc si vous construisez quelque chose sur ces techniques, vous feriez mieux d'espérer qu'elles ne deviennent pas populaires, sinon vous êtes foutu parce que tout à coup, votre base de code est impossible à maintenir et cela a besoin d'énormes changements.
Phoshi

23
Je ne comprends pas pourquoi cette réponse a un score aussi élevé. 3. et 4. pour l'un sont tout simplement stupides et n'équivaudront à aucune sécurité.
Matti Virkkunen

117

À aucun moment de l'histoire de l'informatique, il n'a été possible d'empêcher la rétro-ingénierie des logiciels lorsque vous en donnez une copie de travail à votre attaquant. De plus, selon toute probabilité, cela ne sera jamais possible .

Cela dit, il existe une solution évidente: ne donnez pas vos secrets à votre attaquant. Bien que vous ne puissiez pas protéger le contenu de votre APK, ce que vous pouvez protéger est tout ce que vous ne distribuez pas. Il s'agit généralement d'un logiciel côté serveur utilisé pour des choses comme l'activation, les paiements, l'application des règles et d'autres morceaux de code juteux. Vous pouvez protéger des actifs précieux en ne les distribuant pas dans votre APK. Au lieu de cela, configurez un serveur qui répond aux demandes de votre application, "utilise" les actifs (quoi que cela puisse signifier), puis renvoie le résultat à l'application. Si ce modèle ne fonctionne pas pour les actifs que vous avez en tête, vous voudrez peut-être repenser votre stratégie.

De plus, si votre objectif principal est d'empêcher le piratage d'applications : ne vous embêtez même pas. Vous avez déjà dépensé plus de temps et d'argent sur ce problème qu'aucune mesure anti-piratage ne pourrait espérer vous sauver. Le retour sur investissement pour résoudre ce problème est si faible qu'il n'est même pas logique d'y penser.


21
Le premier paragraphe est la meilleure réponse. Si votre attaquant contrôle le matériel, il pourra toujours vaincre votre logiciel d'une manière ou d'une autre. Tout ce qui doit vraiment être protégé doit rester sur le matériel que vous contrôlez, c'est aussi simple que cela. Et le dernier paragraphe, sur le retour sur investissement, est également sur place.
Daniel Pryden

88

Première règle de sécurité des applications: toute machine à laquelle un attaquant obtient un accès physique ou électronique illimité appartient désormais à votre attaquant, quel que soit l'endroit où il se trouve réellement ou ce que vous avez payé pour cela.

Deuxième règle de sécurité des applications: tout logiciel qui laisse les limites physiques à l'intérieur desquelles un attaquant ne peut pas pénétrer appartient désormais à votre attaquant, quel que soit le temps que vous avez passé à le coder.

Troisième règle: toute information qui laisse ces mêmes limites physiques qu'un attaquant ne peut pas pénétrer appartient maintenant à votre attaquant, quelle que soit sa valeur pour vous.

Les fondements de la sécurité des technologies de l'information reposent sur ces trois principes fondamentaux; le seul ordinateur vraiment sécurisé est celui enfermé dans un coffre-fort, à l'intérieur d'une cage Farraday, à l'intérieur d'une cage en acier. Il y a des ordinateurs qui passent la majeure partie de leur durée de vie dans cet état; une fois par an (ou moins), ils génèrent les clés privées des autorités de certification racine de confiance (devant une multitude de témoins avec des caméras enregistrant chaque centimètre de la pièce dans laquelle ils se trouvent).

Maintenant, la plupart des ordinateurs ne sont pas utilisés dans ces types d'environnements; ils sont physiquement en plein air, connectés à Internet via un canal radio sans fil. En bref, ils sont vulnérables, tout comme leur logiciel. Il ne faut donc pas leur faire confiance. Il y a certaines choses que les ordinateurs et leurs logiciels doivent savoir ou faire pour être utiles, mais il faut veiller à ce qu'ils ne puissent jamais en savoir ou en faire assez pour causer des dommages (du moins pas des dommages permanents en dehors des limites de cette seule machine). ).

Vous saviez déjà tout cela; c'est pourquoi vous essayez de protéger le code de votre application. Mais c'est là que réside le premier problème; les outils d'obscurcissement peuvent rendre le code un gâchis pour qu'un humain essaie de creuser, mais le programme doit encore s'exécuter; cela signifie que le flux logique réel de l'application et les données qu'elle utilise ne sont pas affectés par l'obscurcissement. Étant donné un peu de ténacité, un attaquant peut simplement désobscurcir le code, et ce n'est même pas nécessaire dans certains cas où ce qu'il regarde ne peut être autre chose que ce qu'il cherche.

Au lieu de cela, vous devriez essayer de vous assurer qu'un attaquant ne peut rien faire avec votre code, quelle que soit la facilité avec laquelle il en obtient une copie claire. Cela signifie, pas de secrets codés en dur, car ces secrets ne sont pas secrets dès que le code quitte le bâtiment dans lequel vous l'avez développé.

Ces valeurs-clés que vous avez codées en dur doivent être entièrement supprimées du code source de l'application. Au lieu de cela, ils devraient être dans l'un des trois endroits; mémoire volatile sur l'appareil, ce qui est plus difficile (mais toujours pas impossible) pour un attaquant d'obtenir une copie hors ligne de; en permanence sur le cluster de serveurs, dont vous contrôlez l'accès avec une main de fer; ou dans un deuxième magasin de données sans rapport avec votre appareil ou vos serveurs, comme une carte physique ou dans la mémoire de votre utilisateur (ce qui signifie qu'il finira par être dans la mémoire volatile, mais il n'est pas nécessaire que cela dure longtemps).

Considérez le schéma suivant. L'utilisateur entre ses informations d'identification pour l'application de la mémoire dans l'appareil. Vous devez, malheureusement, vous assurer que l'appareil de l'utilisateur n'est pas déjà compromis par un enregistreur de frappe ou un cheval de Troie; le mieux que vous puissiez faire à cet égard est de mettre en œuvre une sécurité multifactorielle, en se souvenant des informations d'identification difficiles à truquer sur les appareils que l'utilisateur a utilisés (MAC / IP, IMEI, etc.) et en fournissant au moins un canal supplémentaire en laquelle une tentative de connexion sur un appareil inconnu peut être vérifiée.

Les informations d'identification, une fois entrées, sont masquées par le logiciel client (à l'aide d'un hachage sécurisé) et les informations d'identification en texte brut sont supprimées; ils ont atteint leur objectif. Les informations d'identification obscurcies sont envoyées via un canal sécurisé au serveur authentifié par certificat, qui les hache à nouveau pour produire les données utilisées pour vérifier la validité de la connexion. De cette façon, le client ne sait jamais ce qui est réellement comparé à la valeur de la base de données, le serveur d'application ne connaît jamais les informations d'identification en clair derrière ce qu'il reçoit pour la validation, le serveur de données ne sait jamais comment les données qu'il stocke pour la validation sont produites, et un homme dans le milieu ne voit que du charabia même si le canal sécurisé a été compromis.

Une fois vérifié, le serveur retransmet un jeton sur le canal. Le jeton n'est utile que dans la session sécurisée, est composé de bruit aléatoire ou d'une copie chiffrée (et donc vérifiable) des identifiants de session, et l'application cliente doit envoyer ce jeton sur le même canal au serveur dans le cadre de toute demande faire quelque chose. L'application client le fera plusieurs fois, car elle ne peut rien faire impliquant de l'argent, des données sensibles ou quoi que ce soit qui pourrait être dommageable en soi; il doit plutôt demander au serveur d'effectuer cette tâche. L'application cliente n'écrira jamais aucune information sensible dans la mémoire persistante sur l'appareil lui-même, du moins pas en texte brut; le client peut demander au serveur via le canal sécurisé une clé symétrique pour crypter toutes les données locales dont le serveur se souviendra; dans une session ultérieure, le client peut demander au serveur la même clé pour déchiffrer les données à utiliser dans la mémoire volatile. Ces données ne seront pas non plus la seule copie; tout ce que le client stocke doit également être transmis sous une forme ou une autre au serveur.

De toute évidence, cela rend votre application fortement dépendante de l'accès à Internet; l'appareil client ne peut exécuter aucune de ses fonctions de base sans une connexion et une authentification appropriées par le serveur. Pas différent de Facebook, vraiment.

Maintenant, l'ordinateur que l'attaquant veut est votre serveur, car c'est lui et non l'application / l'appareil client qui peut lui faire gagner de l'argent ou causer de la peine à d'autres personnes pour son plaisir. C'est bon; vous en avez beaucoup plus pour votre argent en dépensant de l'argent et des efforts pour sécuriser le serveur qu'en essayant de sécuriser tous les clients. Le serveur peut se trouver derrière toutes sortes de pare-feu et autres dispositifs de sécurité électroniques, et peut en outre être physiquement sécurisé derrière de l'acier, du béton, un accès par carte / broche et une surveillance vidéo 24h / 24. Votre attaquant devrait en effet être très sophistiqué pour accéder directement à tout type d'accès au serveur, et vous devriez (devriez) le savoir immédiatement.

Le mieux qu'un attaquant puisse faire est de voler le téléphone et les informations d'identification d'un utilisateur et de se connecter au serveur avec les droits limités du client. Si cela se produit, tout comme la perte d'une carte de crédit, l'utilisateur légitime devrait être invité à appeler un numéro 800 (de préférence facile à retenir, et non au dos d'une carte qu'il porterait dans son sac à main, son portefeuille ou sa mallette qui pourrait être volé à côté de l'appareil mobile) à partir de tout téléphone auquel ils peuvent accéder et qui les connecte directement à votre service client. Ils déclarent que leur téléphone a été volé, fournissent un identifiant unique de base et le compte est verrouillé, toutes les transactions que l'attaquant a pu traiter sont annulées et l'attaquant est de retour à la case départ.


1
réponse parfaite !! J'ai adoré votre façon d'obtenir des données du serveur avec un jeton crypté, je pense que c'est presque impossible à décoder après cela.
dharam

Je sais que c'est un peu tard mais qu'en est-il de l'accès à la partie serveur? Des services comme Microsoft azure vous fournissent quelque chose comme ceci pour accéder à leur serveur: MobileServiceClient mClient = new MobileServiceClient ("MobileServiceUrl", // Remplacer par l'URL du site ci-dessus "AppKey", // remplacer par la clé d'application ceci) et à peu près tous ceux qui a accès à qui peut accéder à leur serveur et le modifier
edwinj

@edwinj - Aucun problème en informatique qui ne peut être résolu avec une autre couche d'indirection. Votre extrait de code donne l'idée de base pour accéder à un service client mobile Azure; il fournit un niveau de sécurité de base contre les "drive-bys" de la porte d'entrée de Microsoft. Vous pouvez à son tour ajouter des couches supplémentaires, telles que la nécessité d'une clé de session (essentiellement ce qu'est le jeton chiffré) sur tout appel de service, et pour obtenir cette clé, elles doivent d'abord s'authentifier avec une combinaison de connaissances des informations d'identification et du schéma de chiffrement.
KeithS

1
Une des meilleures réponses.
debo.stackoverflow

64

 1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

Ce n'est pas possible

 2. Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?

Lorsque quelqu'un change une extension .apk en .zip, puis après avoir décompressé, quelqu'un peut facilement obtenir toutes les ressources (sauf Manifest.xml ), mais avec APKtool, on peut également obtenir le vrai contenu du fichier manifeste. Encore une fois, non.

 3. Existe-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source de mon fichier APK?

Encore une fois, non, mais vous pouvez empêcher jusqu'à un certain niveau, c'est-à-dire

  • Téléchargez une ressource à partir du Web et effectuez un processus de cryptage
  • Utiliser une bibliothèque native précompilée (C, C ++, JNI, NDK)
  • Toujours effectuer un hachage ( touches MD5 / SHA ou toute autre logique)

Même avec Smali, les gens peuvent jouer avec votre code. Dans l'ensemble, ce n'est pas POSSIBLE.


7
@TrevorBoydSmith: Le cryptage n'aide pas beaucoup lorsque le système d'exploitation est open source et rootable. Le système a besoin d'une clé pour déchiffrer l'APK et exécuter des trucs. Et si le système a une clé et que j'ai un accès illimité au système, alors je sais où trouver la clé et je peux y accéder. Cela signifie que j'ai la clé maintenant aussi .
cHao

4
@TrevorBoydSmith: C'est la partie "comment faire", cependant, qui tue toute l'idée. Il n'y a tout simplement aucun moyen d'exécuter directement du code crypté; à un moment donné, le code déchiffré doit être disponible. Ce qui signifie (1) qu'il doit y avoir une clé (à laquelle j'ai, en tant que root, probablement accès), et (2) je pourrais même être en mesure de trouver la copie claire dans la RAM et de ne pas vous soucier du cryptage de toute façon.
cHao

3
@TrevorBoydSmith: Le problème est que, dans ce cas, vous ne pouvez tout simplement pas augmenter suffisamment le coût pour que cela ne vaille pas la peine. Nous ne parlons pas ici de clés de forçage brutal; nous parlons déjà de les avoir - le système d'exploitation doit avoir des clés, et nous avons le système d'exploitation. La seule façon de résoudre ce problème serait de rendre le système d'exploitation impossible à rooter. Bonne chance avec ça; même Apple ne peut pas le gérer. :)
cHao

3
@TrevorBoydSmith: Je ne pense pas qu'il soit impossible d' augmenter le coût en général . Je pense (et dis), en particulier , que votre suggestion est impossible - parce qu'elle l'est . MATLAB n'est pas Android et a certaines libertés que Android n'a pas. En particulier, il a de l'obscurcissement de son côté; il est beaucoup plus difficile de masquer une clé de chiffrement. Android ne peut pas faire ça. Quiconque possède le code source saurait où se cachent les clés et disposerait d'un outil pour les récupérer dans les 10 minutes suivant l'annonce de la fonctionnalité. Ce n'est pas seulement possible de le faire; c'est carrément trivial .
cHao

6
@TrevorBoydSmith: Je n'ai rien insisté de la sorte. Ce que j'insiste, c'est que l'électricité statique, le changement, le déplacement, etc. n'ont pas d'importance . Dans un système d'exploitation open source, le chiffrement seul ne peut pas protéger le code contre quiconque pourrait le désosser. Parce que je peux lire le code qui ferait le décryptage, quelle que soit la façon dont la clé est acquise, utilisée et / ou stockée, je peux voir comment vous l'avez fait et la reproduire - encore plus facilement que je ne pourrais inverser un super-secret code d'application.
cHao

37

Il n'est pas possible d'éviter à 100% l'ingénierie inverse de l'APK Android, mais vous pouvez utiliser ces méthodes pour éviter d'extraire plus de données, comme le code source, les actifs de votre APK et les ressources:

  1. Utilisez ProGuard pour masquer le code d'application

  2. Utilisez NDK en utilisant C et C ++ pour mettre votre cœur d'application et sécuriser une partie du code dans des .sofichiers

  3. Pour sécuriser les ressources, n'incluez pas toutes les ressources importantes dans le dossier des ressources avec APK. Téléchargez ces ressources au moment du premier démarrage de l'application.


7
Le troisième facilite vraiment le travail des attaquants. Renifler la communication réseau est plus facile que la rétro-ingénierie.
2015

Pour résoudre le problème du troisième, on pourrait crypter le contenu téléchargé et / ou utiliser une connexion cryptée (par exemple SSL / TLS)
Stradivari

1
Le chiffrement de la connexion protège contre les personnes qui reniflent ou modifient le trafic. Dans le cas où l'utilisateur lui-même est malveillant (c'est-à-dire qu'il a votre apk et qu'il essaie de le pirater), il obtiendra toujours le contenu en utilisant votre application, en extrayant des ressources en tant qu'utilisateur root; mais oui, cela aide contre de simples attaques de reniflement.
Kevin Lee

Ajoutant à cela: 4) utilisez dexguard pour une obfuscation plus élevée, mais c'est payé 5) utilisez le fichier OBB pour le téléchargement des actifs au moment du téléchargement de l'application, cela aidera à réduire la taille de l'application également
Ashok Kumar

35

Les développeurs peuvent prendre les mesures suivantes pour empêcher le vol d'un fichier APK,

  • la manière la plus élémentaire est d'utiliser des outils comme ProGuardpour brouiller leur code, mais jusqu'à présent, il a été assez difficile d'empêcher complètement quelqu'un de décompiler une application.

  • J'ai également entendu parler d'un outil HoseDex2Jar . Il s'arrête Dex2Jaren insérant du code inoffensif dans un APK Android qui confond et désactive Dex2Jaret protège le code de la décompilation. Cela pourrait en quelque sorte empêcher les pirates de décompiler un APK en code java lisible.

  • Utilisez une application côté serveur pour communiquer avec l'application uniquement lorsque cela est nécessaire. Cela pourrait aider à empêcher les données importantes.

Du tout, vous ne pouvez pas protéger complètement votre code contre les pirates potentiels. D'une manière ou d'une autre, vous pourriez rendre la tâche difficile et un peu frustrante pour eux pour décompiler votre code. L'un des moyens les plus efficaces consiste à écrire en code natif (C / C ++) et à le stocker sous forme de bibliothèques compilées.


3
HoseDex2Jar est presque inutile. Il ne fait que «confondre» dex2jar et peut facilement être bloqué. smali / apktool, etc. fonctionnent très bien avec les fichiers APK «arrosés».
Nikolay Elenkov

@NikolayElenkov Savez-vous comment fonctionne HoseDex2Jar? Ce qu'ils ont utilisé pour éviter ou pour confondre dex2jar.Parce que je ne peux pas télécharger mon fichier apk sur le Web pour utiliser HoseDex2Jar. Si je peux faire quelque chose comme HoseDex2Jar pour confondre dex2jar, il sera difficile de pirater en utilisant l'outil dex2jar.
sachin003

1
Vous avez peut-être mal compris mon point de vue: ce que fait HoseDex2Jar est de reconditionner votre APK afin que l'outil dex2jar populaire ne puisse pas (hors de la boîte) l'inverser. Cependant, d'autres outils peuvent le faire, et il est très facile de le vaincre en général. Inutile de l'utiliser. Personne n'a mentionné le truc Dexguard I (par l'auteur de ProGuard; pas gratuit), mais c'est du travail à regarder. Il fait quelque chose de plus que l'obscurcissement «régulier».
Nikolay Elenkov

C ++ ne peut jamais être inversé? c'est difficile mais possible. et il existe des outils pour vous aider, comme hex-rays.com/products/decompiler/index.shtml (oui, ils ont la version ARM. ce n'est pas si facile à obtenir).
dkzm

oui, @VikartiAnatra: J'ai également mentionné D'une manière ou d'une autre, vous pourriez rendre les choses difficiles
Sahil Mahajan Mj

24

Voici quelques méthodes que vous pouvez essayer:

  1. Utilisez l' obscurcissement et des outils comme ProGuard .
  2. Chiffrez une partie de la source et des données.
  3. Utilisez une somme de contrôle intégrée propriétaire dans l'application pour détecter la falsification.
  4. Introduisez du code pour éviter de charger dans un débogueur, c'est-à-dire, laissez l'application avoir la capacité de détecter le débogueur et de quitter / tuer le débogueur.
  5. Séparez l'authentification en tant que service en ligne.
  6. Utiliser la diversité des applications
  7. Utilisez la technique de l'empreinte digitale pour, par exemple, les signatures matérielles des appareils de différents sous-systèmes avant d'authentifier l'appareil.

23

 1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

Impossible

 2. Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?

Impossible

 3. Existe-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source de mon fichier APK?

Plus difficile - possible, mais en fait, ce sera plus difficile principalement pour l'utilisateur moyen, qui cherche simplement des guides de piratage. Si quelqu'un veut vraiment pirater votre application, elle sera piratée tôt ou tard.


22

 1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

C'est impossible

 2. Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?

Les développeurs peuvent prendre des mesures telles que l'utilisation d'outils comme ProGuard pour brouiller leur code, mais jusqu'à présent, il a été assez difficile d'empêcher complètement quelqu'un de décompiler une application.

C'est un très bon outil et peut augmenter la difficulté de «renverser» votre code tout en réduisant l'empreinte de votre code.

Prise en charge intégrée de ProGuard: ProGuard est désormais fourni avec les outils SDK. Les développeurs peuvent désormais masquer leur code en tant que partie intégrante d'une build de version.

 3. Existe-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source de mon fichier APK?

Pendant mes recherches, j'ai découvert HoseDex2Jar . Cet outil protégera votre code de la décompilation, mais il ne semble pas possible de protéger complètement votre code.

Quelques liens utiles, vous pouvez vous y référer.


21

La principale question ici est de savoir si les fichiers dex peuvent être décompilés et la réponse est qu'ils peuvent être "en quelque sorte". Il y a des démonteurs comme dedexer et smali .

ProGuard, correctement configuré, obscurcira votre code. DexGuard, qui est une version commerciale étendue de ProGuard, peut vous aider un peu plus. Cependant, votre code peut toujours être converti en smali et les développeurs ayant une expérience de rétro-ingénierie pourront comprendre ce que vous faites à partir du smali.

Peut-être choisissez-vous une bonne licence et appliquez-la par la loi de la meilleure façon possible.


4
En guise de remarque (avertissement: IANAL) - la licence ne protégera pas l'application dans toutes les juridictions en toutes circonstances (par exemple, dans certains pays d'Europe, elle est autorisée à être démontée afin d'augmenter la compatibilité).
Maciej Piechotka

12

Votre client devrait embaucher quelqu'un qui sait ce qu'il fait, qui peut prendre les bonnes décisions et vous guider.

Parlez ci-dessus du fait que vous avez une certaine capacité à modifier le système de traitement des transactions sur le backend est absurde - vous ne devriez pas être autorisé à effectuer de telles modifications architecturales, alors ne vous attendez pas à pouvoir le faire.

Ma justification à ce sujet:

Étant donné que votre domaine est un traitement de paiement, il est sûr de supposer que les normes PCI DSS et / ou PA DSS (et les lois fédérales / étatiques potentielles) seront importantes pour votre entreprise - pour être conforme, vous devez montrer que vous êtes en sécurité. Pour ne pas être sûr, découvrez (via des tests) que vous n'êtes pas sûr, puis corrigez, retestez, etc. jusqu'à ce que la sécurité puisse être vérifiée à un niveau approprié = chemin coûteux, lent et à haut risque vers le succès. Pour faire ce qu'il faut, réfléchissez bien à l'avance, engagez des talents expérimentés dans le travail, développez de manière sécurisée, puis testez, réparez (moins), etc. (moins) jusqu'à ce que la sécurité puisse être vérifiée à un niveau approprié = peu coûteux, rapide, moyen de réussite à faible risque.


8

En tant que personne qui a beaucoup travaillé sur les plates-formes de paiement, y compris une application de paiement mobile (MyCheck), je dirais que vous devez déléguer ce comportement au serveur, aucun nom d'utilisateur ni mot de passe pour le processeur de paiement (quel qu'il soit) ne devrait être stocké ou codé en dur dans l'application mobile, c'est la dernière chose que vous voulez, car la source peut être comprise même si vous masquez le code.

De plus, vous ne devriez pas stocker de cartes de crédit ou de jetons de paiement sur l'application, tout devrait être, encore une fois, délégué à un service que vous avez créé, cela vous permettra également plus tard, d'être plus conforme à la norme PCI, et les sociétés de cartes de crédit ont gagné ne souffle pas dans ton cou (comme ils l'ont fait pour nous).


7

Les autres réponses votées ici sont correctes. Je veux juste fournir une autre option.

Pour certaines fonctionnalités que vous jugez importantes, vous pouvez héberger le contrôle WebView dans votre application. La fonctionnalité serait alors implémentée sur votre serveur Web. Il semblera qu'il s'exécute dans votre application.


@Sarel Botha oui pour les écrans IMP J'ai déjà utilisé la vue Web et oui, c'est aussi une façon de maintenir la sécurité, j'accepte votre réponse.
sachin003

7

Si nous voulons rendre l'ingénierie inverse (presque) impossible, nous pouvons placer l'application sur une puce hautement inviolable, qui exécute toutes les choses sensibles en interne et communique avec un protocole pour rendre le contrôle de l'interface graphique possible sur l'hôte. Même les puces inviolables ne sont pas 100% résistantes aux fissures; ils ont juste placé la barre beaucoup plus haut que les méthodes logicielles. Bien sûr, cela n'est pas pratique: l'application nécessite une petite verrue USB qui contient la puce à insérer dans l'appareil.

La question ne révèle pas la motivation de vouloir protéger cette application si jalousement.

Si l'objectif est d'améliorer la sécurité du mode de paiement en masquant les failles de sécurité éventuelles de l'application (connues ou non), elle est complètement erronée. Les bits sensibles à la sécurité devraient en fait être open source, si cela est possible. Vous devriez faciliter le plus possible la tâche à tout chercheur en sécurité qui examine votre application pour trouver ces éléments et examiner leur fonctionnement, et pour vous contacter. Les applications de paiement ne doivent contenir aucun certificat intégré. Autrement dit, il ne devrait y avoir aucune appliaction de serveur qui fait confiance à un appareil simplement parce qu'il a un certificat fixe de l'usine. Une transaction de paiement doit être effectuée uniquement sur les informations d'identification de l'utilisateur, en utilisant un protocole d'authentification de bout en bout correctement conçu qui empêche de faire confiance à l'application, à la plate-forme ou au réseau, etc.

Si le but est d'empêcher le clonage, à l'exception de cette puce inviolable, vous ne pouvez rien faire pour protéger le programme contre l'ingénierie inverse et la copie, de sorte que quelqu'un incorpore un mode de paiement compatible dans sa propre application, donnant devenir des "clients non autorisés". Il existe des moyens de rendre difficile le développement de clients non autorisés. L'une serait de créer des sommes de contrôle basées sur des instantanés de l'état complet du programme: toutes les variables d'état, pour tout. GUI, logique, peu importe. Un programme clone n'aura pas exactement le même état interne. Bien sûr, c'est une machine à états qui a des transitions d'état similaires visibles de l'extérieur (comme on peut l'observer par les entrées et les sorties), mais à peine le même état interne. Une application serveur peut interroger le programme: quel est votre état détaillé? (c'est à dire donnez-moi une somme de contrôle sur toutes vos variables d'état interne). Cela peut être comparé au code client factice qui s'exécute sur le serveur en parallèle, en passant par les transitions d'état authentiques. Un clone tiers devra reproduire tous les changements d'état pertinents du programme authentique afin de donner les bonnes réponses, ce qui entravera son développement.


7

En accord avec @Muhammad Saqib ici: https://stackoverflow.com/a/46183706/2496464

Et @Mumair donne de bonnes étapes de départ: https://stackoverflow.com/a/35411378/474330

Il est toujours prudent de supposer que tout ce que vous distribuez sur l'appareil de votre utilisateur appartient à l'utilisateur. Clair et simple. Vous pouvez peut-être utiliser les derniers outils et procédures pour crypter vos propriétés intellectuelles, mais il n'y a aucun moyen d'empêcher une personne déterminée «d'étudier» votre système. Et même si la technologie actuelle peut leur rendre difficile l'accès indésirable, il pourrait y avoir un moyen facile demain, ou même juste l'heure suivante!

Ainsi, voici l'équation:

When it comes to money, we always assume that client is untrusted.

Même dans une économie aussi simple que dans le jeu. (Surtout dans les jeux! Il y a des utilisateurs plus «sophistiqués» et les failles se propagent en quelques secondes!)

Comment pouvons-nous rester en sécurité?

La plupart, sinon la totalité, de nos principaux systèmes de traitement (et de notre base de données bien sûr) situés côté serveur. Et entre le client et le serveur, il y a des communications cryptées, des validations, etc. C'est l'idée du client léger.



4

Schéma de signature APK v2 dans Android N

La classe PackageManager prend désormais en charge la vérification des applications à l'aide du schéma de signature APK v2. Le schéma de signature APK v2 est un schéma de signature de fichier entier qui améliore considérablement la vitesse de vérification et renforce les garanties d'intégrité en détectant toute modification non autorisée des fichiers APK.

Pour conserver la compatibilité descendante, un fichier APK doit être signé avec le schéma de signature v1 (schéma de signature JAR) avant d'être signé avec le schéma de signature v2. Avec le schéma de signature v2, la vérification échoue si vous signez l'APK avec un certificat supplémentaire après avoir signé avec le schéma v2.

La prise en charge du schéma de signature APK v2 sera disponible plus tard dans l'aperçu du développeur N.

http://developer.android.com/preview/api-overview.html#apk_signature_v2


2
La signature Apk v2 empêche uniquement la falsification des ressources, mais ne rend pas la rétro-ingénierie plus difficile…
Louis CAD

1
De plus, vous pouvez simplement supprimer la signature et la signer à nouveau. La signature v2 n'est qu'un bloc de données dans le fichier APK.
Robert

4

Il n'y a aucun moyen d'éviter complètement l'ingénierie inverse d'un APK. Pour protéger les actifs et les ressources des applications, vous pouvez utiliser le chiffrement.

  • Le chiffrement rendra son utilisation plus difficile sans déchiffrement. Choisir un algorithme de chiffrement fort rendra le craquage plus difficile.
  • Ajouter du code d'usurpation dans votre logique principale pour rendre plus difficile le crackage.
  • Si vous pouvez écrire votre logique critique dans n'importe quelle langue maternelle et cela rendra sûrement plus difficile la décompilation.
  • Utilisation de tout cadre de sécurité tiers comme Quixxi

3

Fondamentalement, ce n'est pas possible. Ce ne sera jamais possible. Cependant, il y a de l'espoir. Vous pouvez utiliser un obfuscateur pour le rendre ainsi certaines attaques courantes sont beaucoup plus difficiles à réaliser, y compris des choses comme:

  1. Renommer des méthodes / classes (donc dans le décompilateur, vous obtenez des types comme a.a)
  2. Obscurcir le flux de contrôle (donc dans le décompilateur, le code est très difficile à lire)
  3. Chiffrement des chaînes et éventuellement des ressources

Je suis sûr qu'il y en a d'autres, mais ce sont les principaux. Je travaille pour une entreprise appelée PreEmptive Solutions sur un obfuscateur .NET . Ils ont également un obfuscateur Java qui fonctionne pour Android ainsi qu'un DashO .

L'obscurcissement a toujours un prix, cependant. En particulier, les performances sont généralement moins bonnes et nécessitent généralement un certain temps supplémentaire pour les versions. Cependant, si votre propriété intellectuelle est extrêmement importante pour vous, cela en vaut généralement la peine.

Sinon, votre seul choix est de faire en sorte que votre application Android passe simplement par un serveur qui héberge toute la logique réelle de votre application. Cela a son propre lot de problèmes, car cela signifie que les utilisateurs doivent être connectés à Internet pour utiliser votre application.

De plus, ce n'est pas seulement Android qui a ce problème. C'est un problème sur chaque app store. C'est juste une question de difficulté à accéder au fichier de package (par exemple, je ne pense pas que ce soit très facile sur les iPhones, mais c'est toujours possible).


Malheureusement, si l'on pirate le client (l'application), il pourra voir le format de communication et créer son propre serveur :(
Jocky Doe

3

Il n'est pas possible d'éviter complètement les RE mais en les rendant plus complexes en interne, vous mettez plus de difficulté pour les attaquants à voir le fonctionnement clair de l'application, ce qui peut réduire le nombre de vecteurs d'attaque.

Si l'application gère des données très sensibles, diverses techniques existent qui peuvent augmenter la complexité de la rétro-ingénierie de votre code. Une technique consiste à utiliser C / C ++ pour limiter la manipulation d'exécution facile par l'attaquant. Il existe de nombreuses bibliothèques C et C ++ qui sont très matures et faciles à intégrer avec les offres JNI d'Android. Un attaquant doit d'abord contourner les restrictions de débogage afin d'attaquer l'application à un faible niveau. Cela ajoute encore plus de complexité à une attaque. Les applications Android doivent avoir android: debuggable = ”false” défini dans le manifeste de l'application pour empêcher une manipulation facile par un attaquant ou un malware.

Vérification de trace - Une application peut déterminer si elle est actuellement tracée par un débogueur ou un autre outil de débogage. En cas de traçage, l'application peut effectuer un nombre illimité d'actions de réponse aux attaques, telles que la suppression des clés de chiffrement pour protéger les données utilisateur, la notification à un administrateur de serveur ou d'autres réponses de ce type pour tenter de se défendre. Cela peut être déterminé en vérifiant les indicateurs d'état du processus ou en utilisant d'autres techniques telles que la comparaison de la valeur de retour de ptrace attach, la vérification du processus parent, les débogueurs de liste noire dans la liste des processus ou la comparaison d'horodatages à différents endroits du programme.

Optimisations - Pour masquer les calculs mathématiques avancés et d'autres types de logique complexe, l'utilisation des optimisations du compilateur peut aider à obscurcir le code objet afin qu'il ne puisse pas être facilement démonté par un attaquant, ce qui rend plus difficile pour un attaquant de comprendre le code particulier. Dans Android, cela peut être plus facilement réalisé en utilisant des bibliothèques nativement compilées avec le NDK. De plus, l'utilisation d'un obfuscateur LLVM ou d'un SDK protecteur offrira une meilleure obfuscation du code machine.

Suppression des binaires - La suppression des binaires natifs est un moyen efficace d'augmenter le temps et le niveau de compétence requis d'un attaquant afin de visualiser la composition des fonctions de bas niveau de votre application. En supprimant un binaire, la table des symboles du binaire est supprimée, de sorte qu'un attaquant ne peut pas facilement déboguer ou inverser l'ingénierie d'une application.Vous pouvez faire référence à des techniques utilisées sur des systèmes GNU / Linux comme sstriping ou en utilisant UPX.

Et enfin, vous devez être au courant de l'obfuscation et des outils comme ProGuard.


3

Si votre application est aussi sensible, vous devriez considérer la partie traitement des paiements côté serveur. Essayez de modifier vos algorithmes de traitement des paiements. Utilisez l'application Android uniquement pour collecter et afficher les informations utilisateur (c'est-à-dire le solde du compte) et plutôt que de traiter les paiements dans les codes java, envoyez cette tâche à votre serveur en utilisant un protocole SSL sécurisé avec des paramètres cryptés. Créez une API entièrement cryptée et sécurisée pour communiquer avec votre serveur.

Bien sûr, il peut également être piraté et cela n'a rien à voir avec la protection des codes sources, mais considérez-le comme une autre couche de sécurité pour rendre plus difficile pour les pirates de tromper votre application.


2

Les puces TPM (Trusted Platform Module) ne sont-elles pas censées gérer le code protégé pour vous? Ils deviennent courants sur les PC (en particulier ceux d'Apple) et ils peuvent déjà exister dans les puces de smartphones d'aujourd'hui. Malheureusement, il n'y a pas encore d'API OS pour l'utiliser. Espérons qu'Android ajoutera un support pour cela un jour. C'est également la clé pour nettoyer le contenu DRM (sur lequel Google travaille pour WebM).


2

Rien n'est sécurisé lorsque vous le mettez entre les mains des utilisateurs finaux, mais certaines pratiques courantes peuvent rendre plus difficile pour un attaquant de voler des données.

  • Mettez votre logique principale (algorithmes) côté serveur.
  • Communiquer avec le serveur et le client; assurez-vous que le serveur et le client de communication noir et blanc sont sécurisés via SSL ou HTTPS; ou utiliser d'autres techniques de génération d'algorithmes de paires de clés (ECC, RSA). Assurez-vous que les informations sensibles restent chiffrées de bout en bout.
  • Utilisez les sessions et expirez-les après un intervalle de temps spécifique.
  • Chiffrez les ressources et récupérez-les du serveur à la demande.
  • Ou vous pouvez créer une application hybride qui accède au système via la webviewprotection des ressources + du code sur le serveur

Approches multiples; c'est évident que vous devez sacrifier la performance et la sécurité


2

Je peux voir cette bonne réponse dans ce fil. En plus, vous pouvez utiliser Facebook redexpour optimiser le code. Redex fonctionne au .dexniveau où proguard fonctionne comme .classniveau.



1

Comment puis-je protéger toutes les ressources, les actifs et le code source de l'application afin que les pirates ne puissent en aucun cas pirater le fichier APK?

Un fichier APK est protégé par l' algorithme SHA-1 . Vous pouvez voir certains fichiers dans le dossier META-INF de l'APK. Si vous extrayez un fichier APK et modifiez l'un de ses contenus, puis fermez-le à nouveau et lorsque vous exécutez ce nouveau fichier APK sur une machine Android, cela ne fonctionnera pas, car les hachages SHA-1 ne correspondront jamais.


C'est vrai; mais il est trivial de démissionner de l'APK (avec un certificat différent) et tout fonctionnera à nouveau. Il est possible de vérifier quelle signature a été utilisée pour signer l'APK à partir de l'application elle-même, et de supprimer les erreurs si le certificat change, mais il n'est que légèrement moins trivial de modifier ce code hors de l'application.
David Given

Cela peut empêcher l'appareil Android d'exécuter du code modifié, mais vous pouvez toujours extraire facilement le code pertinent et écrire un nouveau code sur un PC qui fait ce que vous voulez.
Sarel Botha

1

Bien que je convienne qu'il n'y a pas de solution à 100% qui va protéger votre code, la version 3 de HoseDex2Jar est maintenant disponible si vous voulez l'essayer.


1

Outil: En utilisant Proguard dans votre application, il peut être limité à la rétro-ingénierie de votre application


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.