Prácticas recomendadas para aplicaciones Android

Los procedimientos recomendados que se describen en este artículo tienen por finalidad mejorar la compatibilidad entre Citrix Endpoint Management y las aplicaciones móviles para dispositivos Android.

SDK de aplicaciones MDX y empaquetado

Si la aplicación usa el SDK de aplicaciones MDX, debe usar la versión correspondiente de MDX Toolkit para empaquetar. Si las versiones de estos dos componentes no coinciden, el funcionamiento posterior de la aplicación puede no ser correcto.

Para evitar este tipo no problema, empaquete la aplicación con el tipo Premium o General. Eso permite entregar una aplicación empaquetada previamente. Como resultado, el cliente no necesitará empaquetar la aplicación, y así se evitará el uso de un MDX Toolkit de otra versión. Para obtener más información sobre cómo empaquetar aplicaciones, consulte Empaquetar aplicaciones móviles Android.

No bloquee el subproceso principal

No debe usar código de bloqueo cuando ejecute procesos en el subproceso principal. Esta es una directriz de Google, pero es incluso más importante cuando se trata de Citrix Endpoint Management. Algunas acciones pueden tardar más tiempo en una aplicación administrada o pueden incluso bloquear la ejecución posterior del subproceso.

A continuación, dispone de algunos ejemplos de código de bloqueo:

  • Operaciones de archivo o base de datos
  • Operaciones de red

Para mayor claridad, todos los métodos de ciclo de vida típicos de las aplicaciones, como onCreate, se ejecutan en el subproceso principal.

Google ofrece una API StrictMode que puede ayudar a detectar código de bloqueo. Para obtener detalles, consulte esta entrada de blog: https://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html.

Escriba un código sólido

En concreto, es necesario comprobar los valores de retorno o excepciones de filtrado (catch) que devuelven las API de la plataforma. Aunque esta es solo una recomendación frecuente para una mejor programación, es muy importante para las aplicaciones administradas.

Varias API que suelen funcionar siempre fallarán si las directivas de Citrix Endpoint Management bloquean la funcionalidad subyacente. Entre los ejemplos se incluyen las capacidades descritas anteriormente:

  • Las API de red actúan como si no hubiera red alguna.
  • Las API de sensores, como el GPS y la cámara, devuelven valores nulos o inician una excepción.
  • Fallan los intentos dirigidos a una aplicación no administrada.
  • El acceso a los archivos y las bases de datos puede fallar si se intenta desde el subproceso principal. Para obtener más información, consulte las secciones Comprobar la compatibilidad del cifrado de datos y Entropía de usuario en el cifrado, que aparecen más adelante en este artículo.

Cuando se produce un fallo, la aplicación debe poder gestionar correctamente el problema, en lugar de bloquearse.

Limitaciones de enlazado

MDX introduce funcionalidad en una aplicación Android binaria modificando el código DEX en el APK. Lo que presenta varias limitaciones:

  • Puede que Citrix Endpoint Management no gestione correctamente las clases obsoletas de plataformas pertenecientes a las versiones del Android SDK anteriores a la versión 4.0. Debe evitar esas clases obsoletas.
  • La mayor parte de la funcionalidad se inserta en las API de las plataformas Java o Android. Por lo general, no se administra código nativo (C o C++). Una excepción es que el cifrado de archivos se sigue produciendo incluso con el código nativo.
  • El código nativo que usa JNI para acceder a la funcionalidad de Java debe apuntar solamente al código de la aplicación de usuario. En otras palabras, no use JNI para invocar directamente los métodos de las plataformas Java o Android. En su lugar, use el patrón de diseño de proxy para “empaquetar” la clase necesaria de la plataforma en una clase propia de Java. A continuación, invoque la clase del código nativo.

Comprobar la compatibilidad del cifrado de datos

Una de las funciones principales de MDX es que todos los datos que se conservan se cifran de forma transparente. No es necesario modificar la aplicación para obtener esta funcionalidad y, de hecho, no se puede evitar directamente. El administrador puede desactivar el cifrado de forma selectiva o completamente, pero la aplicación no tiene esa opción.

Este es uno de los puntos más densos de MDX y requiere que se entiendan los siguientes puntos:

  • El cifrado de archivos está presente para todo el código Java y nativo que se ejecuta en los procesos administrados.

  • Algunas API de plataforma (como reproductores de medios y soportes de impresión) se ejecutan en realidad en varios procesos independientes del SO. Si usa una API de este tipo, pueden surgir problemas.

    • Ejemplo: La aplicación guarda un archivo en el disco (cifrado) y, a continuación, pasa una referencia del archivo a una API de medios. Esa API de medios intenta leer el archivo, pero no entiende el contenido cifrado. Se produce un error en la API o incluso se bloquea la aplicación.
    • Ejemplo: Crea un identificador de archivo (que inicia un archivo cifrado) y lo entrega a la API de la cámara. El proceso de cámara escribe directamente los datos sin cifrar en el archivo cifrado. Cuando la aplicación intenta leer los datos, estos dejan de estar cifrados, con lo que se producen elementos basura.
  • Una manera de gestionar varios procesos independientes es descifrar un archivo antes de entregárselo a la API relevante. O bien, si la API escribe datos, podría dejar que los escribiera primero para, a continuación, cifrarlos cuando la API haya terminado. Se requieren varios pasos:

    1. Designar un área que permanecerá sin cifrar. Debe documentar este tema de cara a su cliente, ya que entonces un administrador de Citrix Endpoint Management debe crear una directiva de exclusiones de cifrado.
    2. Para descifrar un archivo, cópielo simplemente desde la ubicación normal (cifrada) a la ubicación no cifrada. Tenga en cuenta que debe realizar una copia de bytes, no una operación de mover el archivo.
    3. Para cifrar el archivo, invierta la dirección de las acciones. Copie el archivo desde una ubicación sin cifrar a una cifrada.
    4. Elimine el archivo no cifrado cuando ya no sea necesario.
  • No se admite la asignación de memoria cuando se trata de archivos cifrados. Por lo tanto, si llama a una API que asigna memoria, esta fallará. Debe poder gestionar el error. Si es posible, evite el uso directo e indirecto de la asignación de memoria. Un caso notable de uso indirecto es la biblioteca de terceros SqlCipher.

    Si la asignación de memoria no se puede evitar, el administrador debe especificar una directiva de exclusiones de cifrado en la que se omitan los archivos pertinentes. Debe documentar esta directiva para su cliente.

  • El cifrado agrega un consumo notorio de los recursos. Debe optimizar las operaciones E/S de los archivos para evitar la degradación del rendimiento. Por ejemplo, si lee y escribe repetidamente la misma información, puede que le interese implementar una caché a nivel de aplicación.

  • Las bases de datos son solo archivos y, por lo tanto, también se cifran. El rendimiento también puede ser un problema aquí. El tamaño de la memoria caché estándar para base de datos es de 2000 páginas u 8 megabytes. Si la base de datos es grande, puede aumentar este tamaño.

    El modo SQLite WAL no se admite debido a la limitación en la asignación de memoria.

Entropía de usuario en el cifrado

Una opción de Citrix Endpoint Management para el cifrado requiere que el usuario final introduzca un PIN para que se genere la clave de cifrado. Esta opción se denomina entropía de usuario. Pueden causar un problema relevante para las aplicaciones.

En concreto, no se puede acceder a ningún archivo o base de datos hasta que el usuario introduzca el PIN. Si hay una operación de E/S para acceder a ellos en una ubicación que se ejecuta antes de que aparezca la solicitud del PIN, esa operación siempre fallará. Este impedimento implica:

  • Debe mantener las operaciones de archivo y base de datos fuera del subproceso principal. Por ejemplo, nunca se podrá leer un archivo del método onCreate() del objeto de aplicación.
  • Las operaciones en segundo plano (como servicios o proveedores de contenido) se pueden ejecutar incluso aunque no haya actividad de las aplicaciones en sí. Estos componentes en segundo plano no pueden mostrar la solicitud de PIN y, por lo tanto, no pueden acceder a archivos ni bases de datos. Tenga en cuenta que, una vez que se ejecuta una actividad en la aplicación, las operaciones de segundo plano tienen permiso para realizar operaciones de E/S.

Existen varios mecanismos de fallo si la clave de cifrado no está disponible debido a la entropía de usuario:

  • Si el subproceso principal accede a una base de datos antes de que el PIN esté disponible, se cierra la aplicación.
  • Si no es el subproceso principal el que accede a la base de datos antes de que esté disponible el PIN, ese subproceso se bloquea hasta que se introduzca el PIN.
  • Cuando se trata de un acceso que no sea a la base de datos y se inicia antes de que el PIN esté disponible, la operación de apertura fallará. En el nivel C, se devuelve un error EACCES. En Java, se produce una excepción.

Para que este problema no se dé en la aplicación, realice pruebas con la entropía de usuario habilitada. En Citrix Endpoint Management, la propiedad de cliente llamada “Encrypt secrets using Passcode” agrega la entropía de usuario. Configure dicha propiedad de cliente, que se encuentra inhabilitada de forma predeterminada. Para ello, desde la consola de Citrix Endpoint Management, vaya a Configurar > Parámetros > Más > Propiedades de cliente.

Redes y micro VPN

Se ofrecen varias opciones de directivas Citrix Endpoint Management a los administradores de red. La directiva “Acceso de red” impide, permite o redirige la actividad de red de la aplicación.

Importante:

La versión 18.12.0 de MDX Toolkit incluía nuevas directivas que combinaban o reemplazaban directivas anteriores. La directiva Acceso de red combina las directivas: Acceso de red, Modo VPN preferido y Permite cambio de modo VPN. La directiva Lista de exclusión sustituye a Lista de exclusión de túnel dividido. La directiva “Sesión micro VPN requerida” reemplaza la “Sesión con conexión requerida”. Para obtener información detallada, consulte Novedades en versiones anteriores.

Opciones disponibles:

  • Utilizar parámetros anteriores: Los valores predeterminados son los valores que había establecido en las directivas anteriores. Si cambia esta opción, no debería volver a Utilizar parámetros anteriores. Tenga en cuenta también que los cambios en las nuevas directivas no surtirán efecto hasta que el usuario actualice la aplicación a 18.12.0 o posterior.
  • Bloqueada: Las API de red utilizadas por la aplicación fallarán. Como se indica en la directriz anterior, debe poder gestionar correctamente dicho fallo.
  • Sin restricciones: Todas las llamadas de red se envían directamente, no por túnel.
  • Túnel - VPN completo: Todo el tráfico proveniente de los túneles de las aplicaciones administradas se envía a través de Citrix Gateway.

Limitación: Citrix Endpoint Management no admite servidores de socket. Si se está ejecutando un servidor de socket dentro de la aplicación empaquetada, el tráfico de red dirigido al servidor de socket no se canaliza a través de Citrix Gateway.

Soporte para plataformas de desarrollo de aplicaciones móviles

Las plataformas de algunas aplicaciones presentan problemas de compatibilidad con Citrix Endpoint Management:

  • Con PhoneGap, el servicio de localización no se bloquea.
  • SQLCipher no funciona con cifrado porque usa la asignación de memoria. Una solución es no usar SQLCipher. Otra solución es excluir el archivo de base de datos del cifrado mediante una directiva de exclusiones de cifrado. Un administrador de Citrix Endpoint Management debe configurar la directiva desde la consola de Citrix Endpoint Management.

Sugerencias de depuración

Cuando depure una aplicación empaquetada, tenga en cuenta estos consejos.

  • Determine si el problema está presente en una versión no empaquetada de la aplicación. Si el problema ocurre cuando la aplicación no está empaquetada, utilice las técnicas habituales de depuración.
  • Compruebe si el problema se soluciona cuando desactiva determinadas directivas de Citrix Endpoint Management.
    • Así, puede localizar incompatibilidades. Inhabilitar una directiva significa que MDX deja de aplicar la restricción relacionada, lo que le permite probar las funciones como si la aplicación no se hubiera empaquetado.
    • Si inhabilitar una directiva resuelve el problema, puede que la aplicación no esté buscando correctamente si hay errores en las API asociadas.
  • Si no se ejecuta una aplicación que no se ha modificado pero se ha vuelto a firmar:
    1. Desinstale el contenido jar del APK con JAR:

      jar xvf {some.apk}

    2. Elimine la carpeta META-INF:

      rm -rf META-INF

    3. Vuelva a instalar el contenido jar en un nuevo APK con JAR:

      jar cvf {/tmp/new.apk} *

    4. Firme el nuevo APK con JARSIGNER:

      jarsigner -keystore {some.keystore} -storepass {keystorepassword} -keypass {keypassword} {/tmp/new.apk} {keyalias}

    5. Si la aplicación sigue sin ejecutarse, es que no puede empaquetar la aplicación con un certificado de firma diferente al utilizado por el APK de original.

  • Si no se ejecuta un APK descompilado o recompilado:
    1. Descompile y recompile con APKTOOL:

      apktool d {some.apk} -o {some.directory}

      apktool b {some.directory} -o {new.apk}

    2. Firme el APK con JARSIGNER, como se ha indicado anteriormente.

    3. Si la aplicación sigue sin ejecutarse, se trata de un fallo APKTOOL de terceros.

  • Si no funciona el empaquetado de aplicaciones:
    1. Compruebe si el problema se soluciona tras eliminar la plataforma APKTOOL y volver a empaquetar.
      • Mac o Linux: rm -rf ~/Library/apktool/framework
      • Windows: del /q /s C:\Users\{username}\apktool\framework
    2. Compare el APKTOOL que utiliza el programa de empaquetado con el que se utilizó para descompilar y recompilar en el paso anterior.
      • Si es la misma versión APKTOOL, el fallo proviene del programa de empaquetado.
      • Si se trata de otra versión de APKTOOL, puede que el APKTOOL integrado en la herramienta MDX Toolkit esté defectuoso.
        1. Desinstale el contenido jar de ManagedAppUtility.jar.
        2. Sobrescríbalo con el contenido de APKTOOL.jar que utilizó para empaquetar la aplicación en el paso anterior.
        3. Vuelva a instalar el contenido jar en un nuevo ManagedAppUtility.jar.
        4. Empaquete la aplicación para confirmar que el error se encuentra en el APKTOOL incrustado.
  • Ejecute la aplicación empaquetada y capture información de registro.
    1. Use grep para investigar lo que ocurre en la aplicación.

      Para realizar un seguimiento de las actividades de la aplicación: grep “MDX-Activity”

      Para realizar un seguimiento del bloqueo de la aplicación por parte de MDX: grep “MDX-Locked”

      Para ver ambos registros juntos: egrep “MDX-Act MDX-Loc”
    2. Si se produce un error en que la aplicación no responde, extraiga los seguimientos ANR mediante ADB.

  • Si se produce un problema al interactuar con varias aplicaciones (como cuando se usa “Abrir en”):
    1. Compruebe que las directivas de cifrado y los parámetros del grupo de seguridad son los mismos entre las aplicaciones.
    2. Intente realizar la misma operación con otra aplicación. Es posible que se trate de fallo en una de las aplicaciones que se están probando.
    3. Capture los registros de todas las aplicaciones implicadas. Tenga en cuenta que Secure Hub puede combinar registros y enviarlos desde aplicaciones individuales. En la pantalla “Mis aplicaciones”, deslice el dedo a la derecha hacia la pantalla “Asistencia”. A continuación, haga clic en el botón de ayuda situado en la parte inferior de la pantalla.

Además de las herramientas mencionadas anteriormente, es posible que también pueda ayudarle:

  • AAPT para agregar información acerca de la aplicación.

    aapt dump badging {some.apk}

  • Comando DUMPSYS en el dispositivo.

    adb shell dumpsys 2>&1 | tee {dumpsys.out}

  • DEX2JAR para recompilar clases en pseudo-Java.

    dex2jar {some.apk}

    Convertir clases de aplicaciones empaquetadas de Dex dual:

    apktool d {some.apk} -o {some.dir}

    dex2jar {some.dir}/assets/secondary-1.dex

  • JD-GUI para ver código pseudo-Java.

  • BAKSMALI para descompilar clases de aplicaciones empaquetadas Dex dual.

    • Descompile el APK empaquetado:

      apktool d {some.apk} -o {some.dir}

    • Descompile las clases de aplicación que no se han descompilado con la llamada anterior:

      baksmali {some.dir}/assets/secondary-1.dex -o {some.dir}/smali

Prácticas recomendadas para aplicaciones Android