Comment cacher votre clé API dans Android
Beaucoup applications Android qui interagissent avec le nuage utilisent une architecture client - serveur avec le jeu de téléphone comme un client et une grande partie du levage lourd qui a lieu sur le serveur. Parfois, vous avez le contrôle sur le serveur, et parfois il est un tiers qui fournit les données, par exemple, mises à jour de la circulation, les données du marché boursier, ou des informations météo, etc. Généralement, ces tiers fournisseurs utilisent une clé API comme un mécanisme d'authentification simple pour accorder l'accès à ces ressources, et comme un moyen de payer pour leurs données.
Maintenant, il ya beaucoup de raisons pour lesquelles vous pourriez vouloir garder votre clé API sécuritaire. Évidemment, si vous êtes d'être facturé pour l'accès aux données de l'API, alors vous ne voulez pas que quelqu'un décompiler votre APK, trouvez votre clé API, puis commencer à l'utiliser dans leurs propres applications. Il est soit va vous coûter de l'argent pour ces appels d'API volés, ou pire encore, de créer de frustration pour vos utilisateurs existants si votre API arrête subitement de fonctionner parce que le fournisseur de services cesse votre accès quand il voit l'augmentation de l'activité. Si votre clé API ne devient compromise puis obtenir une nouvelle clé à vos utilisateurs est jamais facile. Avez-vous révoquer l'ancienne clé de l'API et de passer à une nouvelle clé API, laissant potentiellement utilisateurs de versions antérieures brin? Ou voulez-vous garder l'ancienne API clé en vie pendant que vous attendez pour les anciens utilisateurs de mettre à niveau, mais courez le risque de nouvelles fausses accusations? De toute façon ne va pas être à 100% satisfaisant, il est donc préférable d'éviter complètement la situation.
Avant de nous pencher sur les options pour cacher votre clé API, regardons comment quelqu'un peut trouver votre clé API. Il existe deux types de base d'attaque, d'abord par la décompilation l'APK pour voir si il est stocké quelque part dans le code, et d'autre part à l'aide d'un homme dans l'attaque Moyen (MITM) pour voir si elle est transmise de manière non sécurisée sur le web. Pour accéder au trafic réseau le pirate doit enraciner leur téléphone en utilisant quelque chose comme ProxyDroid. Cela permet au trafic d'être interceptées à l'aide de l'outil Charles Proxy ou BurpSuite utilisant une attaque MITM.
Clés API sont souvent envoyés via une URL. Par exemple, vous pouvez faire une demande à l'API Weather Underground en utilisant l'URL suivante,
http://api.wunderground.com/api/2ee858dd063ef50e/conditions/q/MI/Troy.json où 2ee858dd063ef50e est la clé de l'API. Si vous envoyez la demande via HTTP, puis la clé API serait clairement visible pour tous ceux qui font une attaque MITM. Envoi correctement via HTTPS, il sera impossible de voir la clé API via proxy. Note Je utilisé le mot "correctement". Le support est jonchée d'exemples d'attaques MITM où le HTTPS a été intercepté parce que l'application a accepté un certificat SSL faux généré par des outils comme Charles Proxy plutôt que de vérifier qu'il provenait d'une autorité de certification digne de confiance (CA). Nous avons également trouvé des exemples où l'appareil lui-même ne gère pas correctement certs et tout le trafic HTTPS était ouvert à une attaque MITM. Vous devez également faire attention à où les clés API vie avant de monter à l'appel de HTTPS. Nous allons voir que la prochaine.
Dans mon audits des centaines d'applications mobiles Android je l'ai vu de nombreuses tentatives pour cacher la clé API. Dans cet article, nous examinons certains des moyens les développeurs ont essayé de protéger votre clé API.
Les options possibles sont les suivantes:
- Dans les préférences, les actifs financiers ou ressources dossiers partagés
- Hardcoded en Java
- Utilisation du NDK
- API de clé publique / clé privée échange
Dans les préférences, les actifs financiers ou ressources dossiers partagés
Voici un exemple d'une clé API qui a été trouvé en décompressant le fichier APK après qu'il a été retiré le téléphone et en regardant dans le dossier asssets.
0M5WrSiVVUbMohPNDsrAmIb0hR6NftlV9E1hjvA 0M5WrSiVVUbMohPNDsrAmIb0hR6NftlV9E1hjvA 03JOvW5GGOOkIY0n70rIiPPFlZjqOqI3SFhKoYA
L'endroit le plus commun je trouve que les touches de l'API aux développeurs de magasin est dans les préférences partagées, est un exemple ci-dessous. Il est pratique courante de mettre APIkeys dans le dossier des ressources dans l'APK, qui est ensuite stocké dans les préférences partagées après l'application de la première ouverture.
Hardcoded en Java
Une clé API est beaucoup, beaucoup plus de chances d'être trouvé dans le dossier des actifs ou de ressources que dans le code décompilé, car il est beaucoup plus facile de mettre à jour xml que le code compilé. Mais il arrive encore régulièrement. Ci-dessous un exemple d'une clé API trouvé dans une application de la pharmacie qui a été stockée dans un fichier Constants.java.
Constantes de classe com.riis.pharmacy public package {public static final API_TOKEN String = "Nti4kWY-qRHTYq3dsbeip0P1tbGCzs2BAY163ManCAb" -}
Utilisation du NDK
The Native Developpement Kit Android (NDK) vous permet d'écrire du code en C / C ++, et peut être très utile lorsque vous essayez de cacher des choses comme des clés de l'API. Les bonnes nouvelles sont que les bibliothèques NDK ne peuvent pas être décompilé rendre l'information plus difficile à trouver. Le code compilé NDK peut encore être ouvert avec un éditeur hexadécimal, mais par la nature de la clé API, ils sont plus difficiles à repérer dans un éditeur hexadécimal.
# include # includejstring Java _ com _ _ Riis apindk _ _ MainActivity invokeNativeFunction (JNIEnv * env, javaThis jobject) {return (* env) -> NewStringUTF (env, "Nti4kWY-qRHTYq3dsbeip0P1tbGCzs2BAY163ManCAb") -}
Vous devez inclure un appel pour voir si la somme de contrôle correspond à votre APK contraire quelqu'un peut appeler votre bibliothèque NDK en dehors de votre application pour récupérer le mot de passe. Cette approche est finalement ne va pas être assez bon pour empêcher quelqu'un de lire le fichier binaire. Mais il est une meilleure option à considérer si vous avez pas d'autre choix que de mettre les clés de l'API ou de chiffrement sur le dispositif, par exemple si le serveur backend appartient à un fournisseur tiers. Code désassemblé devient aussi rapidement plus difficile à comprendre car il devient plus loin de ces exemples de helloworld simples.
API privée échange publique / clé
Alors que HTTPS cache en toute sécurité la clé API lors de la transmission, la récupération de la clé API à partir du téléphone donc l'appel de HTTPS peut être fait est un réel problème pour les développeurs. Comme nous l'avons vu cache une clé API est pas différente de la façon dont les gens essaient de cacher une clé de chiffrement symétrique (voir mon article précédent sur où stocker vos mots de passe). Toutes ces touches peuvent être récupérés à l'aide de la sauvegarde de la BAD ou de la commande de traction de la BAD et un peu de persévérance. Donc, même si le pirate ne peut pas effectuer un homme dans l'attaque Moyen ils peuvent encore voir comment l'appel est mis en place et l'API qui est utilisée dans l'appel de sorte qu'ils peuvent détourner votre ressource si elle est utile pour eux. Nous pourrions essayer de tenter de chiffrer la clé API sur le téléphone, mais si vous stockez la clé de cryptage sur le téléphone, alors vous êtes simplement en ajoutant une étape supplémentaire pour obtenir la clé API.
Cependant, vous pouvez utiliser un échange de clés API publique / privée pour sauvegarder la clé API, de sorte qu'il ne peut plus être volé. L'inconvénient de l'utilisation échange de clés public / privé pour les mots de passe est que le téléphone ne peut pas être en mode avion lorsque vous vous connectez comme le décryptage a lieu sur un serveur distant. Cela ne vaut pas pour les touches de l'API comme ils sont toujours en utilisant la communication en réseau.
La clé doit d'abord être chiffrée avec la clé publique sur un serveur distant en utilisant votre bibliothèque préférée comme Keyczar de Google. Vous pouvez stocker dans le RES / xml dossier de sorte que vous pouvez le récupérer quand quelqu'un ouvre l'application sur le téléphone, puis le stocker dans les préférences partagées de l'application, ou l'envoyer à l'application à partir du serveur distant afin qu'il puisse être réutilisé en cas de besoin. Lorsque l'appel d'URL est faite la clé API crypté est envoyé via HTTPS, puis décrypté sur le serveur de sorte qu'il peut être comparée à la clé API réel. Vous pouvez également utiliser une autre pièce dynamique des informations telles que le nom d'utilisateur pour vous assurer que la clé API encypted ne peut lui-même être utilisé comme une clé API. Il n'y a rien pour arrêter quelqu'un d'autre d'envoyer la même clé API crypté à partir d'une application différente pour vaincre vos efforts. Vous pouvez arrêter ces attaques par rejeu en cryptant votre clé API avec une seule et unique fois de nombre généré de façon aléatoire ou GUID, connu comme un nonce. Le nonce et la clé de l'API sont envoyés au serveur pour l'authentification de l'API, et la clé API et un nouveau nonce sont envoyés au client pour être sauvé dans les préférences partagées après chaque connexion pour la prochaine utilisation. Chaque nonce généré est enregistré lors de la création et marqué comme utilisé une fois qu'il a été envoyé à partir de n'importe quel client.
Conclusion
Quelle option vous choisissez va probablement être déterminée par le degré de contrôle que vous avez sur le serveur backend. Si vous ne disposez pas de tout contrôle, alors vous allez probablement avoir à cacher la clé API utilisant le NDK. Si vous le faites alors nous vous recommandons le public / privé cryptage de la clé API utilisant nonces pour prévenir toute attaque de relecture. Dans le prochain article, nous allons examiner les implications de sécurité de soutenir les versions antérieures du système d'exploitation Android, ainsi que la façon dont certains téléphones Android sont plus sûrs que d'autres.
A propos de l'auteur
Godfrey Nolan est le fondateur et président de la société de téléphonie mobile et le développement web RIIS LLC basé à Troy, au Michigan, et à Belfast, Northern Ireland.He a eu une saine obsession avec inverse bytecode d'ingénierie. Voir plus de lui ici. Il est également l'auteur de Bulletproof Android: Conseils pratiques pour la création d'applications sécurisées.