2010-12-13 13 views
55

Acabo de ofuscar mi código de Android usando proguard y luego lo descompilé. Hay una serie de cuerdas que realmente me gustaría esconder de miradas indiscretas. Cuando descompilé mi código, las cuerdas estaban ahí para que todos las vieran ... y cambiasen. Una de las cadenas es una URL para mi servidor de licencias y, de hecho, podría cambiar la URL para apuntar a un servidor falso (ya que lanzaré el código del servidor al público). ¿Cuál es la mejor manera de ocultar este tipo de información?Ocultando cadenas en el código ofuscado

Además, noté que las cadenas de la clase R son todos números aleatorios pero no puedo encontrar la clase R en el código descompilado. ¿Dónde está?

Foe ejemplo veo: new SimpleCursorAdapter(localActivity, 2130903058, localCursor, arrayOfString, arrayOfInt);

2130903058 es un archivo de diseño, pero ¿qué es lo que hacen referencia a? El número no significa nada a menos que esté apuntando a algún tipo de dirección.

Respuesta

31

Suponiendo que esté satisfecho con la oscuridad y no con la seguridad, existe una serie de mecanismos que podría utilizar, pero los ofuscadores como Proguard no le podrán ayudar.

Para lograr esto, necesitará hacer la codificación o encriptación de la cadena usted mismo, el enfoque que usa depende de lo que está tratando de defenderse, si solo está tratando de esconderse de la inspección obvia, entonces la codificación puede ser suficiente (ver android.util.Base64, http://developer.android.com/reference/android/util/Base64.html). Tenga en cuenta que la codificación no es de NINGUNA MANERA SEGURA y lo único que hará es eliminar la referencia obvia a su sitio.

Si está tratando de defenderse de algo más, entonces podría pasar a cifrar realmente la cadena, para hacer esto utilizaría un cifrado simétrico como AES a través de javax.crypto.Cipher, http://www.androidsnippets.org/snippets/39/index.html proporciona un ejemplo de uso decente. De nuevo, esto es más molesto que seguro para los piratas informáticos, ya que tendrá que guardar la clave en algún lugar de su contenedor, anulando así cualquier seguridad criptográfica.

Para hacer esto más claro, los pasos básicos serían:

  1. crear manualmente un encriptar su cadena utilizando una clave conocida.
  2. convertir su código para utilizar una versión descifrada de esta cadena, ejemplo:

Antes:

public class Foo { 
    private String mySecret = "http://example.com"; 

    ... 
} 

se convierte en:

public class Foo { 
    private String encrypted = "<manually created encrypted string>"; 
    private String key = "<key used for encryption"; 
    private String mySecret = MyDecryptUtil.decrypt(encrypted, key); 

    ... 
} 

A (buena) alternativa a todo esto está considerando usar una solución drm de terceros, como el servidor de licencias google proporciona http://android-developers.blogspot.com/2010/07/licensing-service-for-android.html. Esto puede ser más seguro que algo en lo que se enrolle, pero está sujeto a limitaciones muy similares a las descritas anteriormente.

+0

¿Qué hay de almacenar algunos archivos de clase en el servidor. ¿Es posible descargar e instalar nuevos archivos de clase después de que una aplicación ya esté instalada? ¿Hay alguna manera de hacer esto de forma segura, es decir, no permitir que alguien copie los archivos de un dispositivo ya registrado y simplemente usarlos? – jax

+18

Puede agregar varias capas pero, al final, no podrá evitar un hacker determinado. En algún momento, es mejor que invierta su tiempo en el resto de su producto, que sea lo suficientemente bueno (lea lo suficientemente valioso) y la gente no querrá robarlo. –

+3

"Al final, no podrás evitar un hacker determinado" -> Estas son las mejores palabras en este largo hilo.Mark tiene razón al decirlo, lo mejor que podemos hacer es desacelerar a los atacantes solamente. – Krypton

0

Deberías buscar en Google "Simplemente otro hacker de Perl". Estos son programas que imprimen una cadena con código ofuscado. También hay muchos ejemplos en otros idiomas, luego Perl en la red.

Wikipedia entry

+0

sí, pero si el pirata informático sabe que ha utilizado JAPH, entonces él/ella puede descifrar fácilmente su clave de API ?? –

6

lo que hice fue crear una larga lista de cadenas estáticas en mi clase de utilidad global. En algún lugar dentro de la larga lista de cadenas, puse mi clave en varios fragmentos.

con mi código es fácil ver cuáles son las claves pasivas reales, pero una vez que el ofuscador funciona, todas las estáticas tendrán nombres como A, B, C, etc. y ya no será fácil detectarlas. .

+0

puede proporcionar un código de muestra de lo que ha dicho. Gracias – Sam

+2

Hola, solo crea una clase pública con todo un montón de 'static 'String variable1 =' 'datos falsos' '; cuando digo" whole bunch "me refiero a un centenar de esas Strings. Es fácil crear un archivo como este usando excel. Luego, esconda algunos datos importantes entre todas esas líneas "falsas". Una vez que el ofuscador se ponga a trabajar, todos estos datos parecerán un desastre. Cuando desee utilizar los datos, combine algunas cadenas individuales para recrear lo que desea ocultar. Puede ir un paso más allá al codificar de alguna manera esas líneas de texto para que se vea aún más como un desastre. –

+0

el punto es: hacer que la persona, que está usando ingeniería inversa en su código, tenga que trabajar para ello. Mientras más desagradable pueda ser, mejor será la probabilidad de que no valga la pena su tiempo. –

2

He usado ROT47. No es muy seguro, pero fácil de usar e implementar, porque es un codificador/decodificador simétrico

0

Puede usar DexGuard para cifrar cadenas, probablemente más eficazmente de lo que podría lograr manualmente y sin cargar el código fuente.

+6

pero DexGuard no es gratis –

+0

Creo que es gratis. Puede enviar un correo electrónico para obtener DexGuard –

+0

¿Puede verificar nuevamente porque según mi conocimiento no es gratis? –

19

Hola a todos.

  1. Let secret sea el texto que desea ocultar

  2. Encuentra la keyhash de su depuración/release.keystore. Deje que k1 sea esta clave.

(herramientas de uso Keytool + OpenSSL: keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64 )

  1. uso de una herramienta (externa al código androide) para cifrar secret con k1

    encrypted = encode (secret, k1)

(Por ejemplo: https://jwt.io, para java: https://github.com/jwtk/jjwt).

  1. En su código java de android escriba encrypted. Cuando se necesita la versión decodificada de encrypted (esto es, el original secret) escriben

original = decode(encrypted, get_my_keyhash_programmatically())

eso es todo. Esto funciona porque el secret original no se muestra en el código fuente de Java, ni el k1 para decodificarlo. Y, si un hacker quiere imprimir su secreto descodificado , debe cambiar el código y volver a compilar, firmando su .apk con su propio keystore no el suyo, y por lo tanto no obteniendo el original correcto secret. (El "único" punto es si k1 se puede deducir de su archivo .apk original).

Nota: get_my_keyhash_programmatically():

try { 
    PackageInfo info = getPackageManager().getPackageInfo(
      "el nombre de su paquete por ejemplo com.tarea.u8", 
      PackageManager.GET_SIGNATURES); 
    for (Signature signature : info.signatures) { 
     MessageDigest md = MessageDigest.getInstance("SHA"); 
     md.update(signature.toByteArray()); 
     Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT)); 
    } 
} catch (PackageManager.NameNotFoundException e) { 

} catch (NoSuchAlgorithmException e) { 

} 
+0

Usted dice "Use una herramienta para cifrar el secreto con k1, por ejemplo: https://jwt.io". Sin embargo, cuando voy a jwt.io y trato de usarlo para crear un token de mi propio JSON, usando mi propia clave (poniéndolo en el campo "secreto"), simplemente me dice que el secreto no es válido. "secreto" es la única cadena que acepta. Entonces, ¿cómo CREO un token con mi propia clave? – jkane001

+1

@Krypton como qué? dame un ejemplo, por favor, de una forma de romper esto – Catalin

+4

Un hacker experimentado debería revertir el codificador de la función java() en 5 minutos, y podría descubrir que el hash de certificación de la aplicación se usa para codificar muy fácilmente. Usando un marco de enganche como XPosed, puede extraer el hash de cert de tu aplicación en tiempo de ejecución. A partir de ese momento, usa ese hash para decodificar todas las cadenas. – Krypton

Cuestiones relacionadas