Prácticas recomendadas para aplicaciones Android
Las prácticas recomendadas que se analizan en este artículo mejoran la compatibilidad entre Citrix Endpoint Management™ y las aplicaciones móviles para dispositivos Android.
SDK de aplicaciones MDX y encapsulado
Si tu aplicación usa el SDK de aplicaciones MDX, debes usar la versión correspondiente de MDX Toolkit para el encapsulado. Una falta de coincidencia de versión entre estos dos componentes podría causar un funcionamiento incorrecto.
- Para evitar tal falta de coincidencia, encapsula la aplicación con un tipo de aplicación Premium o General. Esto te permite entregar una aplicación preencapsulada. Como resultado, tu cliente no necesitará encapsular la aplicación, evitando así el uso de un MDX Toolkit no coincidente. Para obtener detalles sobre el encapsulado de aplicaciones, consulta Encapsular aplicaciones móviles Android.
No bloquees el hilo principal
No debes usar código de bloqueo cuando se ejecuta en el hilo principal. Esta es una directriz de Google, pero es aún más crucial con Citrix Endpoint Management. Algunas acciones pueden tardar más en una aplicación administrada o incluso pueden bloquear la ejecución posterior del hilo.
El código de bloqueo incluye, entre otros, lo siguiente:
- Operaciones de archivos o bases de datos
- Operaciones de red
Para ser claros, todos los métodos del ciclo de vida de la aplicación, como onCreate, se ejecutan en el hilo principal.
Google proporciona una API StrictMode que puede ayudar a detectar código de bloqueo. Para obtener más detalles, consulta esta entrada de blog: https://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html.
-
Escribe código robusto
En particular, debes verificar los valores de retorno o capturar las excepciones de las API del marco de trabajo. Si bien esta es solo una práctica recomendada de programación común, es especialmente importante para las aplicaciones administradas.
Varias API que esperarías que siempre funcionaran fallarán si las directivas de Citrix Endpoint Management bloquean la funcionalidad subyacente. Los ejemplos incluirían cualquiera de las capacidades descritas anteriormente:
- Las API de red fallan como si no hubiera red disponible.
- Las API de sensores, como GPS y cámara, devuelven nulo o lanzan una excepción.
- Los Intents dirigidos a una aplicación no administrada fallan.
- El acceso a archivos y bases de datos podría fallar si se usa desde el hilo principal. Para obtener más detalles, consulta las secciones Compatibilidad con el cifrado de datos y Entropía de usuario de cifrado, más adelante en este artículo.
Cuando encuentres un fallo, tu aplicación debe manejar el problema de forma elegante en lugar de bloquearse.
Limitaciones de enganche (hooking)
MDX inyecta funcionalidad en una aplicación binaria de Android modificando el código DEX en el APK. Hay varios límites presentes:
- Citrix Endpoint Management podría no administrar clases de marco de trabajo obsoletas de las versiones pre-4.0 del SDK de Android. Asegúrate de evitar esas clases obsoletas.
- La mayoría de la funcionalidad se inyecta en las API del marco de trabajo de Java/Android. El código nativo (C/C++) generalmente no se administra. Una excepción es que, incluso para el código nativo, el cifrado de archivos sigue ocurriendo.
- El código nativo que usa JNI para acceder a la funcionalidad de Java solo debe dirigirse al código de la aplicación del usuario. En otras palabras, no uses JNI para invocar directamente métodos del marco de trabajo de Java o Android. En su lugar, usa el patrón de diseño de proxy para “encapsular” la clase de marco de trabajo deseada en una clase Java propia. Luego, invoca tu clase desde el código nativo.
Garantizar la compatibilidad con el cifrado de datos
- Una de las características principales de MDX es que todos los datos persistentes se cifran de forma transparente. No necesitas modificar tu aplicación para obtener esta funcionalidad y, de hecho, no puedes evitarla directamente. El administrador tiene la capacidad de deshabilitar el cifrado de forma selectiva o total, pero la aplicación no.
- Este es uno de los aspectos más pesados de MDX y requiere una comprensión de los siguientes puntos:
-
El cifrado de archivos está presente para todo el código Java y nativo que se ejecuta en procesos administrados.
-
Algunas API del marco de trabajo, como los reproductores multimedia y la compatibilidad con la impresión, en realidad se ejecutan en procesos de SO separados. Si usas una API de este tipo, podrías encontrar problemas.
- Ejemplo: Tu aplicación guarda un archivo en el disco (cifrado) y luego pasa una referencia al archivo a una API multimedia. La API multimedia intenta leer el archivo pero no comprende el contenido cifrado. Falla o incluso bloquea la aplicación.
- Ejemplo: Creas un identificador de archivo (que inicia un archivo cifrado) y se lo das a la API de la cámara. El proceso de la cámara escribe directamente datos sin cifrar en el archivo cifrado. Cuando tu aplicación intenta leer esos datos, los datos se descifran, produciendo basura.
-
Un método para manejar procesos separados es descifrar un archivo antes de entregarlo a la API relevante. O si la API escribe datos, entonces la dejarías escribir primero y luego la cifrarías cuando la API terminara. Se requieren algunos pasos:
-
- Designa un área que permanecerá sin cifrar. Debes documentar esto para tu cliente, porque un administrador de Citrix Endpoint Management debe crear una directiva de exclusión de cifrado.
-
- Para descifrar, simplemente copia el archivo de la ubicación normal (cifrada) a la ubicación descifrada. Ten en cuenta que debes hacer una copia de bytes y no una operación de mover archivo.
-
- Para cifrar, invierte la dirección. Copia de ubicaciones sin cifrar a ubicaciones cifradas.
-
- Elimina el archivo sin cifrar cuando ya no sea necesario.
-
La asignación de memoria no es compatible con archivos cifrados. Si llamas a una API que realiza asignación de memoria, fallará. Debes manejar el error. Si es posible, evita el uso directo e indirecto de la asignación de memoria. Un caso notable de uso indirecto es la biblioteca de terceros SqlCipher.
-
Si no puedes evitar la asignación de memoria, el administrador debe especificar una directiva de exclusión de cifrado que omita los archivos relevantes. Debes documentar esta directiva para tu cliente.
-
El cifrado añade una sobrecarga medible. Asegúrate de optimizar la E/S de archivos para evitar la degradación del rendimiento. Por ejemplo, si lees y escribes repetidamente la misma información, es posible que desees implementar una caché a nivel de aplicación.
-
Las bases de datos son solo archivos y, por lo tanto, también están cifradas. El rendimiento también puede ser un problema aquí. El tamaño estándar de la caché de la base de datos es de 2000 páginas u 8 megabytes. Si tu base de datos es grande, podrías aumentar este tamaño.
- El modo WAL de SQLite no es compatible debido a la limitación de asignación de memoria.
-
Entropía de usuario de cifrado
Una opción de Citrix Endpoint Management para el cifrado requiere que el usuario final ingrese un PIN antes de que se pueda generar la clave de cifrado. Esta opción se llama entropía de usuario. Puede causar un problema particular para las aplicaciones.
Específicamente, no se puede realizar ningún acceso a archivos o bases de datos hasta que el usuario ingrese un PIN. Si una operación de E/S de este tipo está presente en una ubicación que se ejecuta antes de que se pueda mostrar la interfaz de usuario del PIN, siempre fallará. Hay algunas implicaciones:
- Mantén las operaciones de archivos y bases de datos fuera del hilo principal. Por ejemplo, un intento de leer un archivo desde el método
onCreate()del objeto de la aplicación siempre fallará. - Las operaciones en segundo plano, como servicios o proveedores de contenido, pueden ejecutarse incluso si no hay actividad de la aplicación presente. Estos componentes en segundo plano no pueden mostrar la interfaz de usuario del PIN y, por lo tanto, no pueden realizar acceso a archivos o bases de datos. Ten en cuenta que una vez que una actividad se ejecuta en la aplicación, las operaciones en segundo plano pueden realizar operaciones de E/S.
Existen varios mecanismos de fallo si la clave de cifrado no está disponible debido a la entropía del usuario:
- Si el hilo principal accede a una base de datos antes de que el PIN esté disponible, la aplicación se cierra.
- Si un hilo no principal accede a una base de datos antes de que el PIN esté disponible, ese hilo se bloquea hasta que se ingresa el PIN.
- Para el acceso no a la base de datos iniciado antes de que el PIN esté disponible, la operación de apertura fallará. A nivel de C, se devuelve un error
EACCES. En Java, se lanza una excepción.
Para asegurarte de que este problema no esté presente en tu aplicación, realiza pruebas con la entropía de usuario habilitada. La propiedad de cliente de Citrix Endpoint Management, Encrypt secrets using Passcode, añade entropía de usuario. Configuras esa propiedad de cliente, que está deshabilitada de forma predeterminada, en la consola de Citrix Endpoint Management en Configurar > Ajustes > Más > Propiedades de cliente.
Redes y micro VPN
- Los administradores tienen a su disposición varias opciones de política de Citrix Endpoint Management para la configuración de red. La política de acceso a la red impide, permite o redirige la actividad de red de las aplicaciones.
- >Importante:
- > >La versión 18.12.0 de MDX Toolkit incluyó nuevas políticas que combinaron o reemplazaron políticas anteriores. La política de Acceso a la red combina Acceso a la red, Modo VPN preferido y Permitir cambio de modo VPN. La política de Lista de exclusión reemplaza a la lista de exclusión de túnel dividido. La política de Sesión micro VPN requerida reemplaza a la sesión en línea requerida. Para obtener más información, consulta [Novedades de versiones anteriores](/es-es/mdx-toolkit/about-mdx-toolkit/whats-new.html#whats-new-in-earlier-releases).
Las opciones son las siguientes:
- **Usar configuración anterior**: Se establece de forma predeterminada en los valores que habías configurado en las políticas anteriores. Si cambias esta opción, no deberías volver a **Usar configuración anterior**. Ten en cuenta también que los cambios en las nuevas políticas no surten efecto hasta que el usuario actualice la aplicación a la versión 18.12.0 o posterior.
- **Bloqueado**: Las API de red utilizadas por tu aplicación fallarán. Según la directriz anterior, deberías gestionar correctamente dicho error.
- **Sin restricciones**: Todas las llamadas de red van directamente y no se canalizan en túnel.
-
Con túnel - VPN completa: Todo el tráfico de la aplicación administrada se canaliza en túnel a través de Citrix Gateway.
-
Limitación: Citrix Endpoint Management no es compatible con el servidor de sockets. Si un servidor de sockets se está ejecutando dentro de la aplicación encapsulada, el tráfico de red al servidor de sockets no se canaliza en túnel a través de Citrix Gateway.
Compatibilidad con marcos de desarrollo de aplicaciones móviles
Algunos marcos de trabajo de aplicaciones tienen problemas de compatibilidad con Citrix Endpoint Management:
- Con PhoneGap, el servicio de ubicación no está bloqueado.
-
SQLCipher no funciona con el cifrado porque utiliza la asignación de memoria. Una solución es no usar SQLCipher. Una segunda solución es excluir el archivo de la base de datos del cifrado mediante una política de exclusión de cifrado. Un administrador de Citrix Endpoint Management debe configurar la política en la consola de Citrix Endpoint Management.
-
Sugerencias de depuración
Al depurar una aplicación encapsulada, ten en cuenta estas sugerencias.
- Determina si el problema está presente en una versión sin encapsular de la aplicación. Si el problema ocurre cuando no está encapsulada, usa técnicas de depuración normales.
- Intenta desactivar varias políticas de Citrix Endpoint Management.
- Esto puede ayudar a localizar cualquier incompatibilidad. Desactivar una política significa que MDX ya no aplica la restricción relacionada, lo que te permite probar esas funciones como si la aplicación no estuviera encapsulada.
- Si la desactivación de una política soluciona el problema, es posible que la aplicación no esté comprobando si hay errores en las API asociadas.
- Si una aplicación sin modificar pero con nueva firma no se ejecuta:
-
- Desempaqueta el contenido del APK usando JAR:
[[CODE_BLOCK_0]]
-
Elimina la carpeta META-INF:
[[CODE_BLOCK_1]]
-
Vuelve a empaquetar el contenido en un nuevo APK usando JAR:
[[CODE_BLOCK_2]]
-
Firma el nuevo APK usando JARSIGNER:
[[CODE_BLOCK_3]]
-
Si la aplicación sigue sin ejecutarse, no puedes encapsularla usando un certificado de firma diferente al del APK original utilizado.
-
- Si un archivo .apk descompilado o recompilado no se ejecuta:
-
Descompila y recompila usando APKTOOL:
[[CODE_BLOCK_4]]
[[CODE_BLOCK_5]]
-
Firma el APK usando JARSIGNER como se describió anteriormente.
-
Si la aplicación sigue sin ejecutarse, se trata de un error de APKTOOL de terceros.
-
- Si el encapsulado de la aplicación no funciona:
- Intenta eliminar el marco de trabajo de APKTOOL y volver a encapsular.
- Mac/Linux: rm -rf ~/Library/apktool/framework
- Windows: del /q /s C:\Users\{username}\apktool\framework
- Compara qué APKTOOL está utilizando el encapsulador con el que usaste para descompilar y recompilar correctamente en el paso anterior.
- Si es la misma versión de APKTOOL, entonces hay un error en Wrapper.
- Si es una versión diferente de APKTOOL, entonces podría haber un error en el APKTOOL integrado en la utilidad MDX Toolkit.
- Desempaqueta el contenido de ManagedAppUtility.jar.
- Sobrescribe con el contenido de APKTOOL.jar que usaste para encapsular correctamente la aplicación en el paso anterior.
- Vuelve a empaquetar el contenido en un nuevo ManagedAppUtility.jar.
- Encapsula la aplicación para confirmar el error en el APKTOOL incrustado.
- Intenta eliminar el marco de trabajo de APKTOOL y volver a encapsular.
- Ejecuta la aplicación encapsulada y captura información de registro.
-
Usa grep para investigar qué está sucediendo en la aplicación.
Para seguir las actividades de la aplicación: grep “MDX-Activity”
Para seguir el bloqueo de la aplicación por parte de MDX: grep “MDX-Locked”
Para ver ambos registros juntos: egrep “MDX-Act MDX-Loc” -
Si hay un error de la aplicación que no responde, extrae los seguimientos de ANR usando ADB.
-
- Si ocurre un problema al interactuar con varias aplicaciones, como al usar “Abrir en”:
- Verifica que las políticas de cifrado y la configuración del grupo de seguridad sean las mismas entre las aplicaciones.
- Prueba con una aplicación diferente. Podría ser un error en una de las aplicaciones que se están probando.
- Captura registros de todas las aplicaciones involucradas. Ten en cuenta que Secure Hub puede agrupar registros y enviar registros por correo electrónico desde aplicaciones individuales. Desde la pantalla “Mis aplicaciones”, desliza el dedo hacia la derecha hasta la pantalla “Soporte”. Luego, haz clic en el botón “Necesito ayuda” en la parte inferior de la pantalla.
Además de las herramientas mencionadas anteriormente, las siguientes también podrían ser útiles:
-
AAPT para volcar información sobre la aplicación.
[[CODE_BLOCK_6]]
-
Comando DUMPSYS en el dispositivo.
[[CODE_BLOCK_7]]
-
DEX2JAR para recompilar clases en pseudo-Java.
[[CODE_BLOCK_8]]
Convierte clases de aplicaciones encapsuladas Dual-Dex:
[[CODE_BLOCK_9]]
[[CODE_BLOCK_10]]
-
JD-GUI para ver código pseudo-Java.
-
BAKSMALI para descompilar clases de aplicaciones de aplicaciones encapsuladas Dual-Dex.
-
Descompila el APK encapsulado:
[[CODE_BLOCK_11]]
-
Descompila las clases de la aplicación que no se descompilan con la llamada anterior:
[[CODE_BLOCK_12]]
-
En este artículo
- SDK de aplicaciones MDX y encapsulado
- No bloquees el hilo principal
- Escribe código robusto
- Limitaciones de enganche (hooking)
- Garantizar la compatibilidad con el cifrado de datos
- Entropía de usuario de cifrado
- Redes y micro VPN
- Compatibilidad con marcos de desarrollo de aplicaciones móviles
- Sugerencias de depuración