studio purchase play library integrada google facturacion developer app android security bit-manipulation in-app-billing public-key

play - in-app purchase android studio



Android In App Billing: asegurando la clave pública de la aplicación (6)

Siga 3 simples pasos para asegurar la API / clave secreta

Podemos usar Gradle para asegurar la clave API o la clave secreta. Verifica mi answer .

De la aplicación de ejemplo de Android In App Billing versión 3 (TrivialDrive) que viene con 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 string here embedded in the * program, construct the key at runtime from pieces or * use bit manipulation (for example, XOR with some other string) 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. */ String base64EncodedPublicKey = "CONSTRUCT_YOUR_KEY_AND_PLACE_IT_HERE";

Bueno, no estoy seguro de entender esta medida de seguridad. Sé cómo obtener la clave pública de la aplicación (que ya está codificada en base 64) desde Google Play Developer Console.

Lo que no entiendo es esta parte

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

Hasta donde yo sé, esta clave pública es una cadena constante, que se da desde Google durante el proceso de carga de la aplicación.

¿Cómo podemos crear la misma clave mediante programación utilizando cualquier proceso de manipulación de bits? ¿Alguien lo ha hecho antes? ¿Hay algún código de muestra sobre cómo hacer esto?


¿Alguien realmente necesita tu clave privada? Creo que la idea es reemplazarlo . En mi humilde opinión, cualquier manipulación es inútil. Lo único que puede hacer una persona malvada es simplemente inicializar la variable con el valor correcto (su propia clave) una línea antes de la llamada API de google.


Algo como esto:

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

o

String Base64EncodedPublicKey key = DecrementEachletter("Bl4kgle") + GetMiddleBit() + ReverseString("D349824");

o cualquier cosa que no ponga la clave en texto plano de base64 en una sola cadena. Probablemente también sea una buena idea algo que no almacene la clave en base64, ya que los fragmentos de texto de base64 son bastante fáciles de detectar.

No es una forma particularmente BUENA de proteger la llave. Pero protege contra un ataque trivial en el que alguien solo busca a través de cadenas literales en su APK buscando algo que se parece a una clave pública codificada en base64. Al menos haces que los $ # $ # $ ers funcionen un poco.

Presumiblemente las personas malvadas pueden hacer cosas malas si identifican su clave pública. Google parece pensar que sí, al parecer. Puedo adivinar lo que hace este paso, pero no estoy seguro de que realmente quiera especular sobre eso en un foro abierto y dar ideas a nadie. Sin embargo, quieres hacerlo.

El resumen básico de la trama sería que le está dificultando a alguien escribir una aplicación que programáticamente desactive una aplicación.

Se supone que cualquiera que esté haciendo esto se gana la vida craqueando 20 o 30,000 aplicaciones de Android y volviéndolas a publicar. Lo más probable es que suponga que no le tomará más de diez minutos agregar su aplicación a la lista de 20,000 aplicaciones de Android que ya han sido destruidas por un programa, si realmente tienen que hacer un poco de trabajo manual. A menos que tenga una aplicación de nivel superior. Y luego la batalla es potencialmente interminable, y probablemente en última instancia fútil.

Dividir la llave en trozos consecutivos (como se propone en otra respuesta) probablemente no sea lo suficientemente bueno. Porque la clave terminará en cadenas consecutivas en las tablas de constante de cadena en el APK. Demasiado fácil de encontrar con un programa.


Lo que hice fue transformar la clave en una matriz de caracteres, dividirla en dos y luego reconstruirla cuando fuera necesario así:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop); char[] base64KeyByteArray = ArrayUtils.addAll(getPublicKeyChunk1(), getPublicKeyChunk2()); Log.d(TAG, String.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}; }


Puedes dividirlo en pedazos como este

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

Cualquier clase de manipulaciones servirá.

No se puede ocultar la clave pública a la perfección del atacante, solo se necesita manipular la cadena para confundir un atacante un poco

Puede agregar algunas cadenas y eliminarlas cuando sea necesario o dividirlas en fragmentos.


Una alternativa es hacer algunas transformaciones básicas en la clave.

// Replace this with your encoded key. String 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 );

Así que la idea sería poner tu clave original como base64EncodedPublicKey y ejecutar el código anterior, intercambiaría las letras mayúsculas y minúsculas y devolvería el resultado en base64EncodedPublicKey . A continuación, puede copiar el resultado del depurador y pegarlo en el código como el valor base64EncodedPublicKey original. En este punto, la clave se transformará (conmutación de mayúsculas y minúsculas) y, en tiempo de ejecución, la fijará de nuevo en la carcasa correcta y continuará funcionando.

Lo anterior es obviamente un transcodificador bastante básico, pero puede ser más creativo, invertir el orden de AZ, cambiar los números impares y pares, cambiar las vocales para los números pares. El problema aquí es que si pongo el código en el fragmento de arriba que hace un montón de transcodificaciones más interesantes, y luego todos copian y pegan eso en sus proyectos, un cracker podrá fácilmente ver y usar el transcodificador (al mirar esta publicación)! Entonces solo tienes que inventar algunas transformaciones.

Intencionalmente, hice que el trabajo anterior fuera en ambas direcciones (por lo tanto, si lo ejecuta dos veces, recuperará su valor original) ya que facilita la ejecución del algoritmo en la clave original. Creo que está algo ordenado, parece que la clave real está ahí, como texto sin formato, un crack ocasional puede tratar de cambiar esto y luego confundirse cuando no funciona.