Android In App Billing: sécuriser la clé publique de l’application

A partir d’Android Dans App Billing version 3 (TrivialDrive) exemple d’application fourni avec sdk

MainActivity.java

/* base64EncodedPublicKey should be YOUR APPLICATION'S PUBLIC KEY * (that you got from the Google Play developer console). This is not your * developer public key, it's the *app-specific* public key. * * Instead of just storing the entire literal ssortingng here embedded in the * program, construct the key at runtime from pieces or * use bit manipulation (for example, XOR with some other ssortingng) to hide * the actual key. The key itself is not secret information, but we don't * want to make it easy for an attacker to replace the public key with one * of their own and then fake messages from the server. */ Ssortingng base64EncodedPublicKey = "CONSTRUCT_YOUR_KEY_AND_PLACE_IT_HERE"; 

Eh bien, je ne suis pas sûr de comprendre cette mesure de sécurité. Je sais comment obtenir la clé publique de l’application (qui est déjà codée en base 64) à partir de Google Play Developer Console.

Ce que je ne comprends pas c’est cette partie

  /* Instead of just storing the entire literal ssortingng here embedded in the * program, construct the key at runtime from pieces or * use bit manipulation (for example, XOR with some other ssortingng) to hide * the actual key */ 

Pour autant que je sache, cette clé publique est une chaîne constante, fournie par Google lors du téléchargement de l’application.

Comment pouvons-nous créer la même clé par programmation en utilisant un processus de manipulation de bits? Est-ce que quelqu’un l’a déjà fait? Existe-t-il un exemple de code sur la façon de procéder?

Quelque chose comme ça:

 Ssortingng Base64EncodedPublicKey key = "Ak3jfkd" + GetMiddleBit() + "D349824"; 

ou

 Ssortingng Base64EncodedPublicKey key = DecrementEachletter("Bl4kgle") + GetMiddleBit() + ReverseSsortingng("D349824"); 

ou tout ce qui ne met pas la clé en clair en base64 dans une seule chaîne. Probablement aussi quelque chose qui ne stocke pas la clé dans base64 serait une bonne idée, puisque les fragments de texte en base64 bruts sont assez faciles à repérer.

Ce n’est pas un moyen particulièrement judicieux de protéger la clé. Mais il protège contre une attaque insignifiante où quelqu’un cherche simplement à travers des chaînes littérales dans votre fichier APK à la recherche de quelque chose qui ressemble à une clé publique encodée en base64. Au moins, vous faites fonctionner un peu les # $ # $ ers.

Vraisemblablement, les méchants peuvent faire de mauvaises choses s’ils identifient votre clé publique. Google semble le penser, apparemment. Je peux deviner ce que fait cette étape, mais je ne suis pas sûr de vouloir vraiment spéculer là-dessus dans un forum ouvert et donner des idées à quiconque. Vous voulez le faire si.

Le résumé de base de l’insortinggue serait que vous rendiez plus difficile pour quelqu’un d’écrire une application qui dé-LVL par programme une application.

On suppose que quiconque fait cela gagne la vie en déchirant 20 ou 30 000 applications Android et en les republiant. Les chances sont, je suppose qu’ils ne vont pas prendre les dix minutes supplémentaires pour append votre application à la liste des 20 000 applications Android qui ont déjà été cassées par un programme, s’ils doivent faire un peu de travail manuel. Sauf si vous avez une application de premier niveau. Et puis la bataille est potentiellement sans fin et probablement finalement futile.

Diviser la clé en morceaux consécutifs (comme proposé dans une autre réponse) n’est probablement pas suffisant. Parce que la clé se retrouvera dans des chaînes consécutives dans les tables de constantes de chaîne dans l’APK. Trop facile à trouver avec un programme.

Une alternative consiste à effectuer des transformations de base sur la clé.

 // Replace this with your encoded key. Ssortingng base64EncodedPublicKey = ""; // Get byte sequence to play with. byte[] bytes = base64EncodedPublicKey.getBytes(); // Swap upper and lower case letters. for (int i = 0; i < bytes.length; i++) { if(bytes[i] >= 'A' && bytes[i] <= 'Z') bytes[i] = (byte)( 'a' + (bytes[i] - 'A')); else if(bytes[i] >= 'a' && bytes[i] <= 'z') bytes[i] = (byte)( 'A' + (bytes[i] - 'a')); } // Assign back to string. base64EncodedPublicKey = new String( bytes ); 

L'idée serait donc de mettre votre clé d'origine dans base64EncodedPublicKey et d'exécuter le code ci-dessus, il permuterait les lettres majuscules et minuscules et replacerait le résultat dans base64EncodedPublicKey . Vous pouvez ensuite copier le résultat du débogueur et le coller dans le code en tant que valeur base64EncodedPublicKey origine. À ce stade, votre clé sera transformée (les majuscules et les minuscules changent) et lors de l'exécution, elle sera rétablie dans le bon boîtier et continuera à fonctionner.

Ce qui précède est évidemment un transcodage basique, mais vous pouvez être plus créatif, inverser l'ordre de AZ, échanger des nombres impairs et pairs, échanger des voyelles pour des nombres pairs. Le problème ici est que si je mets du code dans l'extrait ci-dessus qui fait un tas de transcodes plus intéressants, et que tout le monde copie et colle cela dans ses projets, un pirate pourra facilement voir et utiliser le transcodage lui-même (en regardant ce post)! Donc, il vous suffit de trouver quelques transformations vous-même.

J'ai volontairement fait travailler les deux éléments dans les deux sens (donc, si vous l'exécutez deux fois, vous récupérerez votre valeur d'origine), car cela facilite l'exécution de l'algorithme sur votre clé d'origine. Je pense que c'est plutôt sympa, il semble que la vraie clé est assise en texte brut, un pirate occasionnel peut essayer de changer cela et être confus quand ça ne marche pas.

Vous pouvez le diviser en morceaux comme celui-ci

 Ssortingng piece1 = "SDFGJKGB4UIH234WE/FRT23RSDF/3DFUISDFVWE"; Ssortingng piece2 = "SDFGJKGB4UIHUISDFVWE"; Ssortingng piece3 = "BDYASGBDNAWGRET24IYE23das4saGBENWKD"; Ssortingng piece4 = "432423SDF23R/+SDDS"; mHelper = new IabHelper(this, piece1 + piece2 + piece3 + piece4); 

Tout type de manipulations fera l’affaire.

Vous ne pouvez pas cacher la clé publique parfaitement à l’attaquant, il vous suffit de manipuler la chaîne pour confondre un attaquant

Vous pouvez append des chaînes et les supprimer au besoin ou les diviser en morceaux.

Ce que j’ai fait a été de transformer la clé en un tableau de caractères, de le diviser en deux et de le reconstruire ensuite lorsque cela est nécessaire:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop); char[] base64KeyByteArray = ArrayUtils.addAll(getPublicKeyChunk1(), getPublicKeyChunk2()); Log.d(TAG, Ssortingng.valueOf(base64KeyByteArray)); } private char[] getPublicKeyChunk1() { return new char[]{82, 73, 67, 66, 73, 106, 65, 78, 66, 103, 107, 113, 104, 107, 105, 71, 57, 119, 79, 66, 65, 81, 69, 70, 65, 65, 79, 67, 65, 81, 56, 65, 77, 73, 73, 66, 67, 103, 75, 67, 65, 81, 69, 65, 121, 55, 81, 76, 122, 67, 105, 80, 65, 110, 105, 101, 72, 66, 53, 57}; } private char[] getPublicKeyChunk2() { return new char[]{82, 43, 68, 47, 79, 121, 122, 110, 85, 67, 118, 89, 108, 120, 43, 49, 80, 100, 67, 108, 55, 90, 57, 103, 119, 57, 87, 78, 79, 111, 53, 101, 80, 71, 117, 74, 104, 82, 87, 97, 100}; } 

Suivez 3 étapes simples pour sécuriser la clé API / Secret

Nous pouvons utiliser Gradle pour sécuriser la clé API ou la clé secrète. Vérifiez ma réponse .

Est-ce que quelqu’un a vraiment besoin de votre clé privée? Je pense que toute l’idée est de le remplacer . IMHO toutes les manipulations sont inutiles. La seule chose à faire par une personne maléfique est juste d’initialiser une variable avec une valeur correcte (sa propre clé), une ligne créée pour l’appel API Google.