Meilleures pratiques pour le stockage et la protection des clés d'API privées dans les applications [fermé]

373

La plupart des développeurs d'applications intégreront des bibliothèques tierces à leurs applications. Si c'est pour accéder à un service, tel que Dropbox ou YouTube, ou pour consigner les plantages. Le nombre de bibliothèques et de services tiers est stupéfiant. La plupart de ces bibliothèques et services sont intégrés en s'authentifiant d'une manière ou d'une autre avec le service, la plupart du temps, cela se fait via une clé API. Pour des raisons de sécurité, les services génèrent généralement une clé publique et privée, souvent également appelée clé secrète. Malheureusement, pour se connecter aux services, cette clé privée doit être utilisée pour s'authentifier et, par conséquent, faire probablement partie de l'application. Inutile de dire que cela fait face à un immense problème de sécurité. Les clés API publiques et privées peuvent être extraites des fichiers APK en quelques minutes et peuvent facilement être automatisées.

En supposant que j'ai quelque chose de similaire à cela, comment puis-je protéger la clé secrète:

public class DropboxService  {

    private final static String APP_KEY = "jk433g34hg3";
    private final static String APP_SECRET = "987dwdqwdqw90";
    private final static AccessType ACCESS_TYPE = AccessType.DROPBOX;

    // SOME MORE CODE HERE

}

Quelle est, selon vous, la manière la meilleure et la plus sûre de stocker la clé privée? Obfuscation, cryptage, qu'en pensez-vous?

Codeur de base
la source
j'avais un magasin en image / png et j'obtiens la clé via png comme BufferReader
Sumit
Je pense que c'est une préoccupation valable et j'ai publié un problème similaire sur la page github de Firebase Android SDK: github.com/firebase/firebase-android-sdk/issues/1583 . Voyons voir si cela est géré.
grebulon

Réponses:

348
  1. En l'état, votre application compilée contient les chaînes de clés, mais aussi les noms constants APP_KEY et APP_SECRET. Extraire des clés d'un tel code auto-documenté est trivial, par exemple avec l'outil Android standard dx.

  2. Vous pouvez appliquer ProGuard. Il laissera les chaînes de touches intactes, mais il supprimera les noms constants. Il renommera également les classes et les méthodes avec des noms courts et dénués de sens, dans la mesure du possible. Extraire les clés prend alors un peu plus de temps, pour déterminer quelle chaîne sert à quelle fin.

    Notez que la configuration de ProGuard ne devrait pas être aussi difficile que vous le craignez. Pour commencer, il vous suffit d'activer ProGuard, comme indiqué dans project.properties. En cas de problème avec les bibliothèques tierces, vous devrez peut-être supprimer certains avertissements et / ou empêcher leur obscurcissement, dans proguard-project.txt. Par exemple:

    -dontwarn com.dropbox.**
    -keep class com.dropbox.** { *; }

    Il s'agit d'une approche par force brute; vous pouvez affiner une telle configuration une fois que l'application traitée fonctionne.

  3. Vous pouvez brouiller les chaînes manuellement dans votre code, par exemple avec un encodage Base64 ou de préférence avec quelque chose de plus compliqué; peut-être même du code natif. Un pirate devra alors effectuer une rétro-ingénierie statique de votre encodage ou intercepter dynamiquement le décodage au bon endroit.

  4. Vous pouvez appliquer un obfuscateur commercial, comme le frère spécialisé de ProGuard ProGuard, DexGuard . Il peut également chiffrer / masquer les chaînes et les classes pour vous. Extraire les clés prend alors encore plus de temps et d'expertise.

  5. Vous pourrez peut-être exécuter des parties de votre application sur votre propre serveur. Si vous pouvez y garder les clés, elles sont en sécurité.

En fin de compte, c'est un compromis économique que vous devez faire: quelle est l'importance des clés, combien de temps ou de logiciels pouvez-vous vous permettre, à quel point les pirates informatiques sont intéressés par les clés, combien de temps voudront-ils dépenser, combien vaut un délai avant que les clés ne soient piratées, à quelle échelle les pirates réussis distribueront-ils les clés, etc. De petites informations comme les clés sont plus difficiles à protéger que des applications entières. Intrinsèquement, rien du côté client n'est incassable, mais vous pouvez certainement relever la barre.

(Je suis le développeur de ProGuard et DexGuard)

Eric Lafortune
la source
2
@EricLafortune ne fait-il aucune différence si la chaîne de clé privée est stockée dans la classe Java par rapport au XML de ressource de chaîne?
Alan
1
@EricLafortune Est-il désormais possible d'utiliser le système Android Keystore pour stocker les clés en toute sécurité? ( developer.android.com/training/articles/keystore.html )
David Thomas
1
@DavidThomas: Avez-vous essayé d'utiliser le magasin de clés. Je veux masquer une clé API écrite en classe Java. Veuillez répondre
Sagar Trehan
1
Android KeyStore est-il utile pour cela? ( developer.android.com/training/articles/… )
Weishi Zeng
1
Je ne comprends pas # 5. N'a-t-il pas les mêmes problèmes exacts que le problème d'origine?
Pete
80

Peu d'idées, à mon avis seule la première donne une garantie:

  1. Gardez vos secrets sur un serveur sur Internet et, si nécessaire, saisissez-les et utilisez-les. Si l'utilisateur est sur le point d'utiliser Dropbox, rien ne vous empêche de faire une demande à votre site et d'obtenir votre clé secrète.

  2. Mettez vos secrets en code jni, ajoutez du code variable pour rendre vos bibliothèques plus grandes et plus difficiles à décompiler. Vous pouvez également diviser la chaîne de clés en quelques parties et les conserver à divers endroits.

  3. utilisez l'obfuscateur, mettez également du code haché secret et, plus tard, décochez-le lorsque vous en avez besoin.

  4. Mettez votre clé secrète en tant que derniers pixels de l'une de vos images dans les ressources. Ensuite, au besoin, lisez-le dans votre code. L'obscurcissement de votre code devrait aider à masquer le code qui le lira.

Si vous voulez voir rapidement à quel point il est facile de lire votre code apk, saisissez APKAnalyser:

http://developer.sonymobile.com/knowledge-base/tool-guides/analyse-your-apks-with-apkanalyser/

marcinj
la source
46
si l'utilisateur peut décompiler l'application bien qu'il puisse probablement déterminer la demande qui a été faite à votre propre serveur et l'exécuter simplement pour obtenir le secret. Pas de solution miracle ici mais faites quelques pas et je parie que tout ira bien! Si votre application est très populaire, mais peut-être pas .. Excellentes idées!
Matt Wolfe
3
oui, le numéro 1 ne donne aucune garantie.
marcinj
42
J'aime vraiment l'idée de cacher les clés dans les images. +1
Igor Čordaš
1
@ MarcinJędrzejewski Voulez-vous expliquer davantage (avec un exemple ou du code coupé de préférence) sur la quatrième solution? Je vous remercie.
Dr.jacky
2
@ Mr.Hyde c'est ce qu'on appelle la stéganographie, son chemin trop complexe pour donner un exemple de code ici, vous pouvez trouver des exemples sur google. J'en ai trouvé un ici: dreamincode.net/forums/topic/27950-steganography . L'idée est géniale mais comme le code apk peut être décompilé, il gâche sa beauté.
marcinj
32

Une autre approche consiste à ne pas avoir le secret sur l'appareil en premier lieu! Voir Techniques de sécurité des API mobiles (en particulier la partie 3).

En utilisant la tradition séculaire de l'indirection, partagez le secret entre votre point de terminaison API et un service d'authentification d'application.

Lorsque votre client souhaite effectuer un appel API , il demande au service d'authentification de l'application de l'authentifier (à l'aide de techniques d'attestation à distance puissantes) et il reçoit un jeton limité dans le temps (généralement JWT ) signé par le secret.

Le jeton est envoyé avec chaque appel d'API où le point de terminaison peut vérifier sa signature avant d'agir sur la demande.

Le secret réel n'est jamais présent sur l'appareil; en fait, l'application n'a aucune idée si elle est valide ou non, elle jute les demandes d'authentification et transmet le jeton résultant. Comme avantage de l'indirection, si vous souhaitez changer le secret, vous pouvez le faire sans que les utilisateurs mettent à jour leurs applications installées.

Donc, si vous souhaitez protéger votre secret, ne pas l'avoir dans votre application en premier lieu est une très bonne façon de procéder.

Skip Hovsmith
la source
5
Ce devrait être la réponse acceptée.
ortonomy
4
Le problème persiste lorsque vous souhaitez accéder au service d'authentification. Il vous donnera un identifiant client et un secret client. Où devrions-nous les sauver?
Ashi
ne résout pas les API privées où vous devez d'abord vous authentifier auprès de votre API pour l'utiliser. où obtenez-vous les informations d'identification pour tous les utilisateurs de l'application?
Kibotu
25

Ancienne voie non sécurisée:

Suivez 3 étapes simples pour sécuriser l'API / la clé secrète ( ancienne réponse )

Nous pouvons utiliser Gradle pour sécuriser la clé API ou la clé secrète.

1. gradle.properties (Propriétés du projet): créer une variable avec la clé.

GoolgeAPIKey = "Your API/Secret Key"

2. build.gradle (Module: app): Définissez la variable dans build.gradle pour y accéder en activité ou en fragment. Ajoutez le code ci-dessous aux buildTypes {}.

buildTypes.each {
    it.buildConfigField 'String', 'GoogleSecAPIKEY', GoolgeAPIKey
}

3. Accédez-y dans Activity / Fragment par l'application BuildConfig:

BuildConfig.GoogleSecAPIKEY

Mise à jour :

La solution ci-dessus est utile dans le projet open source pour valider via Git. (Merci à David Rawson et riyaz-ali pour votre commentaire).

Selon les commentaires de Matthew et Pablo Cegarra, la méthode ci-dessus n'est pas sécurisée et Decompiler permettra à quelqu'un d'afficher le BuildConfig avec nos clés secrètes.

Solution :

Nous pouvons utiliser NDK pour sécuriser les clés API. Nous pouvons stocker des clés dans la classe C / C ++ native et y accéder dans nos classes Java.

Veuillez suivre ce blog pour sécuriser les clés d'API à l'aide de NDK.

Un suivi sur la façon de stocker des jetons en toute sécurité dans Android

SANAT
la source
4
le stockage d'une clé dans un fichier gradle est-il sécurisé?
Google
4
@Google gradle.propertiesne doit pas être enregistré dans Git, c'est donc un moyen de garder le secret hors du code source engagé, au moins
David Rawson
4
Cela n'empêche pas la clé API d'être intégrée dans le résultat apk(il sera ajouté au BuildConfigfichier généré ), bien que ce soit certainement une bonne idée de gérer différentes clés API (par exemple dans un projet open source)
riyaz-ali
5
L'utilisation d'un décompilateur Java permettra à quelqu'un d'afficher le fichier BuildConfig et "GoogleSecAPIKEY"
Matthew
3
Votre BuildConfig.javafichier aura la clé sous forme de texte brut. Ce n'est pas mieux que ce que le PO fait déjà.
iceman
16

La clé App-Secret doit rester privée - mais lors de la libération de l'application, certains gars peuvent l'inverser.

pour ces gars-là, il ne se cachera pas, verrouillez ProGuardle code. Il s'agit d'un refactoriseur et certains obscurcisseurs payants insèrent quelques opérateurs au niveau du bit pour récupérer lejk433g34hg3 chaîne. Vous pouvez augmenter de 5 à 15 minutes le piratage si vous travaillez 3 jours :)

Le meilleur moyen est de le garder tel quel, à mon humble avis.

Même si vous stockez côté serveur (votre PC), la clé peut être piratée et imprimée. Peut-être que cela prend le plus de temps? Quoi qu'il en soit, il s'agit de quelques minutes ou de quelques heures dans le meilleur des cas.

Un utilisateur normal ne décompilera pas votre code.


la source
1
Eh bien - pas la réponse que j'espérais obtenir =) ... Je pensais que vous pouvez assurer une grande sécurité :(
Basic Coder
désolé ce n'est pas comme vous vouliez une solution brillante et ultra sûre, mais pour ceux qui peuvent utiliser le compilateur, le décompilateur il n'y a pas de code java sûr: même le code natif peut être visualisé avec hexa viewer et decrtypé. Au moins vaut la peine d'essayer ...
1
Proguard n'obscurcira pas la clé réelle cependant ..? La meilleure chose à faire est une simple routine d’enregistrement / décryptage, que l’obscurcissement cachera.
Doomsknight
3
il est "visible" la routine de déchiffrement, il est facile de faire l'inverse et vous avez la chaîne d'origine
14

Une solution possible consiste à coder les données dans votre application et à utiliser le décodage lors de l'exécution (lorsque vous souhaitez utiliser ces données). Je recommande également d'utiliser progaurd pour rendre difficile la lecture et la compréhension du code source décompilé de votre application. par exemple, j'ai mis une clé codée dans l'application, puis j'ai utilisé une méthode de décodage dans mon application pour décoder mes clés secrètes au moment de l'exécution:

// "the real string is: "mypassword" "; 
//encoded 2 times with an algorithm or you can encode with other algorithms too
public String getClientSecret() {
    return Utils.decode(Utils
            .decode("Ylhsd1lYTnpkMjl5WkE9PQ=="));
}

Le code source décompilé d'une application proguarded est le suivant:

 public String c()
 {
    return com.myrpoject.mypackage.g.h.a(com.myrpoject.mypackage.g.h.a("Ylhsd1lYTnpkMjl5WkE9PQ=="));
  }

Au moins, c'est assez compliqué pour moi. c'est la façon dont je fais quand je n'ai pas d'autre choix que de stocker une valeur dans mon application. Bien sûr, nous savons tous que ce n'est pas la meilleure façon, mais cela fonctionne pour moi.

/**
 * @param input
 * @return decoded string
 */
public static String decode(String input) {
    // Receiving side
    String text = "";
    try {
        byte[] data = Decoder.decode(input);
        text = new String(data, "UTF-8");
        return text;
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return "Error";
}

Version décompilée:

 public static String a(String paramString)
  {
    try
    {
      str = new String(a.a(paramString), "UTF-8");
      return str;
    }
    catch (UnsupportedEncodingException localUnsupportedEncodingException)
    {
      while (true)
      {
        localUnsupportedEncodingException.printStackTrace();
        String str = "Error";
      }
    }
  }

et vous pouvez trouver autant de classes de chiffrement avec une petite recherche dans google.

Milad Faridnia
la source
13

En ajoutant à la solution @Manohar Reddy, la base de données Firebase ou Firebase RemoteConfig (avec une valeur par défaut Null) peut être utilisé:

  1. Chiffrez vos clés
  2. Stockez-le dans la base de données Firebase
  3. Obtenez-le au démarrage de l'application ou chaque fois que nécessaire
  4. déchiffrer les clés et les utiliser

Qu'est-ce qui est différent dans cette solution?

  • aucun credintials pour firebase
  • l'accès à Firebase est protégé, donc seule l'application avec un certificat signé a le privilège de faire des appels API
  • chiffrement / déchiffrement pour empêcher l'interception des intermédiaires. Appelle déjà https à firebase
Ayman Al-Absi
la source
avec tout le respect de cette solution, nous sommes toujours le premier carré. Au lieu d'utiliser des informations d'identification, vous proposez d'utiliser un certificat. Quiconque est capable de voler vos informations d'identification est capable de voler votre certificat signé.
Ashi
Un avantage cependant, avec la solution suggérée, nous ajoutons une complication de plus devant le pirate.
Ashi
11

Cet exemple a plusieurs aspects différents. Je mentionnerai quelques points qui, je pense, n'ont pas été explicitement abordés ailleurs.

Protéger le secret en transit

La première chose à noter est que l'accès à l'API Dropbox à l'aide de leur mécanisme d' authentification d'application vous oblige à transmettre votre clé et votre secret. La connexion est HTTPS, ce qui signifie que vous ne pouvez pas intercepter le trafic sans connaître le certificat TLS. Il s'agit d'empêcher une personne d'intercepter et de lire les paquets pendant son trajet de l'appareil mobile vers le serveur. Pour les utilisateurs normaux, c'est un très bon moyen de garantir la confidentialité de leur trafic.

Ce qui n'est pas bon, c'est d'empêcher une personne malveillante de télécharger l'application et d'inspecter le trafic. Il est vraiment facile d'utiliser un proxy man-in-the-middle pour tout le trafic entrant et sortant d'un appareil mobile. Il ne nécessiterait aucun démontage ni ingénierie inverse du code pour extraire la clé et le secret de l'application dans ce cas en raison de la nature de l'API Dropbox.

Vous pouvez effectuer un épinglage qui vérifie que le certificat TLS que vous recevez du serveur est celui que vous attendez. Cela ajoute une vérification au client et rend plus difficile l'interception du trafic. Cela rendrait plus difficile l'inspection du trafic en vol, mais la vérification de l'épinglage se produit chez le client, il serait donc toujours possible de désactiver le test d'épinglage. Cela rend cependant les choses plus difficiles.

Protéger le secret au repos

Dans un premier temps, l'utilisation de quelque chose comme proguard aidera à rendre moins évident où se trouvent les secrets. Vous pouvez également utiliser le NDK pour stocker la clé et le secret et envoyer des demandes directement, ce qui réduirait considérablement le nombre de personnes possédant les compétences appropriées pour extraire les informations. Un obscurcissement supplémentaire peut être obtenu en ne stockant pas les valeurs directement en mémoire pendant une durée quelconque, vous pouvez les crypter et les décrypter juste avant l'utilisation comme suggéré par une autre réponse.

Options plus avancées

Si vous êtes maintenant paranoïaque à l'idée de mettre le secret n'importe où dans votre application et que vous avez le temps et l'argent pour investir dans des solutions plus complètes, vous pouvez envisager de stocker les informations d'identification sur vos serveurs (en supposant que vous en ayez). Cela augmenterait la latence de tous les appels à l'API, car elle devra communiquer via votre serveur, et pourrait augmenter les coûts de fonctionnement de votre service en raison de l'augmentation du débit de données.

Vous devez ensuite décider de la meilleure façon de communiquer avec vos serveurs pour vous assurer qu'ils sont protégés. Ceci est important pour éviter que les mêmes problèmes ne se reproduisent avec votre API interne. La meilleure règle empirique que je puisse donner est de ne transmettre aucun secret directement à cause de la menace de l'homme du milieu. Au lieu de cela, vous pouvez signer le trafic à l'aide de votre secret et vérifier l'intégrité de toutes les demandes envoyées à votre serveur. Une façon standard de procéder consiste à calculer un HMAC du message saisi sur un secret. Je travaille dans une entreprise qui a un produit de sécurité qui opère également dans ce domaine, c'est pourquoi ce genre de choses m'intéresse. En fait, voici un article de blog de l'un de mes collègues qui revient sur la plupart de cela.

Combien dois-je faire?

Avec des conseils de sécurité comme celui-ci, vous devez prendre une décision en termes de coûts / avantages sur la difficulté à faire en sorte que quelqu'un pénètre. Si vous êtes une banque protégeant des millions de clients, votre budget est totalement différent de celui qui prend en charge une application dans leur temps libre. Il est pratiquement impossible d'empêcher quelqu'un de briser votre sécurité, mais dans la pratique, peu de gens ont besoin de toutes les cloches et sifflets et avec quelques précautions de base, vous pouvez faire du chemin.

ThePragmatist
la source
1
Vous venez de copier et coller ceci à partir d'ici: hackernoon.com/mobile-api-security-techniques-682a5da4fe10 sans en mentionner la source.
ortonomy
1
@ortonomy Je suis d'accord qu'il aurait dû citer l'article que vous avez lié, mais il l'a peut-être oublié parce que les deux travaillent au même endroit ...
Exadra37
2
L'article de Skip et le blog sur lequel ils sont basés sont également sortis une semaine après ma réponse.
ThePragmatist
8

La solution la plus sécurisée consiste à conserver vos clés sur un serveur et à acheminer toutes les demandes nécessitant cette clé via votre serveur. De cette façon, la clé ne quitte jamais votre serveur, aussi longtemps que votre serveur est sécurisé, votre clé l'est également. Bien sûr, il y a un coût de performance avec cette solution.

Bernard Igiri
la source
32
Le problème est - pour atteindre ce serveur qui contient tous les secrets, je devrais utiliser une autre clé secrète - je me demande où je vais le garder? ;) Ce que j'essaie de dire est - Ce n'est pas non plus la meilleure solution (ne pense pas qu'il y ait une solution idéale ici)
Mercury
Ce n'est pas vrai, votre serveur est entièrement sous votre contrôle. Ce qu'il vous faut dépend entièrement de vous.
Bernard Igiri
5
Pouvez-vous expliquer ici comment le client peut crypter les données qu'il souhaite envoyer au serveur, alors que les clés sont côté serveur? et si votre réponse sera - Le serveur envoie des clés au client - Donc ça doit être sécurisé aussi! donc encore une fois pas de solution magique! tu ne vois pas?!
Mercury
2
@BernardIgiri, puis de nouveau à la case 1. Supposons que le téléphone crée une connexion aléatoire et que le serveur accepte cela et envoie une broche (c'est le soi-disant serveur privé dont nous parlons). Ensuite, la personne qui démonte votre application voit que tout ce qu'il faut pour accéder à votre serveur privé est juste une connexion aléatoire qu'il peut créer lui-même. Dites-moi ce qui l'empêche d'en créer un et d'accéder à votre serveur? En fait, quelle est la différence entre votre solution et le fait de stocker une clé de connexion ou une clé API sur le serveur principal (dont nous voulions stocker les informations d'identification sur notre serveur privé)
Ken
3
@ken Le nombre aléatoire est authentifié par rapport au numéro de téléphone et à l'accès physique à ses messages texte. Si quelqu'un vous trompe, vous avez ses informations. Si cela ne suffit pas, forcez-les à créer un compte utilisateur complet et un mot de passe. Si cela ne suffit pas, procurez-vous également une carte de crédit. Si ce n'est pas assez bon, faites-les appeler. Si ce n'est pas assez bon, rencontrez-les face à face. Dans quelle mesure voulez-vous être sûr / gênant?
Bernard Igiri
7

Gardez le secret firebase databaseet obtenez-en lorsque l'application démarre, c'est bien mieux que d'appeler un service Web.

Manohar Reddy
la source
13
mais qu'en est-il des informations d'identification pour Firebase?
the_joric
2
Malheureusement, la base de données Firebase ne fonctionne pas en Chine.
Konjengbam
9
n'a pas de sens, les attaquants peuvent vous voir les détails de la base de feu à partir du code décompilé et obtenir toutes les données de votre base de données
user924
3
Je pense que c'est la meilleure solution car Firebase Apps utilise SHA1 pour autoriser l'accès au serveur. La décompilation du code n'aidera pas à appeler Firebase car la nouvelle application de pirate devrait utiliser le tampon d'application exact pour accéder à Firebase. De plus, la clé stockée doit être chiffrée avant d'être stockée dans la base de données Firebase et déchiffrée une fois reçue pour éviter l'interception par l'homme du milieu.
Ayman Al-Absi,
Lorsque vous obtenez le secret de la base de données Firebase via le réseau, comment est-ce plus sécurisé que d'obtenir le même secret d'un autre service Web via un canal sécurisé (https)? Peux-tu expliquer?
Csaba Toth le
6

Quoi que vous fassiez pour sécuriser vos clés secrètes ne sera pas une vraie solution. Si le développeur peut décompiler l'application, il n'y a aucun moyen de sécuriser la clé, masquer la clé n'est qu'une sécurité par obscurité, tout comme l'obscurcissement du code. Le problème avec la sécurisation d'une clé secrète est que pour la sécuriser, vous devez utiliser une autre clé et cette clé doit également être sécurisée. Pensez à une clé cachée dans une boîte verrouillée avec une clé. Vous placez une boîte à l'intérieur d'une pièce et verrouillez la pièce. Il vous reste une autre clé à sécuriser. Et cette clé sera toujours codée en dur dans votre application.

Donc, à moins que l'utilisateur n'entre un code PIN ou une phrase, il n'y a aucun moyen de masquer la clé. Mais pour ce faire, vous devez avoir un schéma de gestion des codes PIN se produisant hors bande, c'est-à-dire via un canal différent. Certainement pas pratique pour sécuriser les clés de services comme les API Google.

user1611728
la source
5

Âge ancien poste, mais toujours assez bon. Je pense que le cacher dans une bibliothèque .so serait génial, en utilisant NDK et C ++ bien sûr. Les fichiers .so peuvent être visualisés dans un éditeur hexadécimal, mais bonne chance pour décompiler cela: P

Ahmed Awad
la source
9
Les utilisateurs peuvent facilement effectuer des appels de fonction à la bibliothèque partagée et obtenir tout ce qui s'y cache. Pas besoin de le décopiler.
david72
5
Selon androidauthority.com/… il n'y a aucun moyen sûr de le faire dans Android pour le moment.
david72
1
@AhmedAwad Je ne comprends pas pourquoi il y a 3 votes positifs. n'importe qui pourrait facilement décompiler l'application et voir comment les points d'entrée ndk sont appelés: /
Johny19
1
Cette réponse est presque l'une des meilleures options, mais l'auteur doit mentionner qu'il est très important que vous incluiez un appel (à l'intérieur de votre bibliothèque NDK) pour voir si la somme de contrôle correspond à votre APK, sinon quelqu'un peut appeler votre bibliothèque NDK en dehors de votre application
Stoycho Andreev
@Sniper ce serait génial, sauf qu'il a un gros problème. Comment savez-vous quel fichier "appelle" la méthode native? Si vous codez en dur le nom de l'apk à vérifier, tant mieux, mais si je fais mon apk "hack" le même dossier que le "bon" apk? Il vérifiera que le "bon" apk a une bonne somme de contrôle, et il me permettra d'exécuter cette méthode native. À moins qu'il n'y ait un moyen de connaître le fichier de l'appelant du côté JNI / C ++, alors c'est inutile comme les autres options.
SocketByte
5

La seule véritable façon de garder ces informations privées est de les conserver sur votre serveur et de demander à l'application d'envoyer quoi que ce soit au serveur, et le serveur interagit avec Dropbox. De cette façon, vous ne distribuez JAMAIS votre clé privée dans n'importe quel format.

pseudo
la source
11
Mais comment empêchez-vous le reste du monde d'appeler le serveur?
user2966445
Si par "le serveur" vous voulez dire votre serveur Web où se trouvent les informations d'identification - vous pouvez utiliser n'importe quelle méthode de votre choix. authentification simple avec nom d'utilisateur / mot de passe, oauth, répertoire actif, etc. etc. Cela dépend vraiment de votre application.
Nick
Peut-être que je manque quelque chose, mais cela ne nécessite-t-il pas encore le stockage des informations d'identification dans l'application?
user2966445
3
D'accord, mais vous avez dit que l'application s'authentifierait d'abord avec le serveur. Cela ne signifie-t-il pas de stocker un autre ensemble d'informations d'identification dans l'application? Je comprends que le serveur gèrerait les appels Dropbox réels.
user2966445
4
Eh bien, cela pourrait signifier cela, mais c'est une autorisation complètement distincte. Mais ce n'est pas obligatoire. Le cas d'utilisation dont je parle est que l'utilisateur de votre application aurait une connexion à votre application, par exemple en utilisant Facebook ou Twitter. Vous ne stockez pas leurs informations d'identification dans votre application, vous ne les connaissez même pas. Ce processus d'autorisation leur permet d'accéder à votre serveur api, qui a les informations d'identification à dropbox, mais aucune application ou utilisateur n'y a accès directement.
Nick
0

Sur la base d'une expérience amère, et après avoir consulté un expert IDA-Pro, la meilleure solution consiste à déplacer une partie clé du code dans une DLL / SharedObject, puis à la récupérer à partir d'un serveur et à la charger lors de l'exécution.

Les données sensibles doivent être encodées car il est très facile de faire quelque chose comme ceci:

$ strings libsecretlib.so | grep My
  My_S3cr3t_P@$$W0rD
RonTLV
la source
3
Et où stockez-vous les informations d'identification pour ledit serveur?
ZX9