Por Iván Santos González y Mireia Scholz
Durante los últimos meses, en uno de los proyectos en los que colaboramos, hemos trabajado tanto en desarrollo nativo de aplicaciones móviles, como en desarrollo web (front y back). De forma muy resumida: la aplicación móvil envía mensajes al back mediante POST requests, el back los almacena en la base de datos y el front los muestra en un dashboard.
Por defecto, Android no confía en conexiones no seguras (HTTP), que son las que inicialmente estábamos utilizando para enviar los mensajes al back. Por esto, permitimos estas conexiones para poder seguir trabajando.
AndroidManifest.xml
|
|
Con esto, ya podíamos seguir haciendo nuestras pruebas en local y en las máquinas del entorno producción, al menos mientras utilizaremos conexiones HTTP.
Cuando llegó la hora de añadir el certificado al back, redirigimos todo el tráfico a HTTPS, así que creíamos que ya no habría más problemas. Sin embargo, tampoco podíamos hacer peticiones a nuestro backend (ahora con HTTPS) en local:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
Por partes ¿Qué es un trust anchor? ¿Dónde debería estar?, ¿y dónde lo está buscando?
Estuvimos una semana entera intentando hacer que esto funcionara (seguro que a algún compi le suena 👀) y vamos a contarles cómo lo solucionamos.
Buscando en internet, encontramos muchos “workarounds” para solucionar este problema, como añadir “parches” al código de producción o permitir TODAS las conexiones, vinieran de dónde vinieran. Nada de esto nos convenció, así que seguimos buscando hasta encontrar este artículo en lo profundo de la documentación de Android Developers.
La solución es generar nuestra propia autoridad certificadora (CA), para a su vez generar un certificado de cliente. Tendríamos que añadir el certificado de la CA que acabamos de generar a la aplicación de Android, para que la acepte como CA de confianza; y, por otra parte, habría que añadir el keystore (que internamente incluye el de la CA también) a nuestro backend. Vamos a verlo en detalle:
Para importar esta CA en la aplicación Android, debemos indicarlo en un fichero de configuración, que a su vez debemos referenciar desde el manifiesto de la aplicación. Basta con añadir la subsección android:networkSecurityConfig="@xml/network_security_config", en el archivo AndroidManifest.xml, dentro de la sección application. En este caso, @xml/network_security_config hace referencia a un fichero de configuración que debe ser creado en el directorio xml y cuyo contenido debe ser el siguiente.
|
|
De esta manera, no será necesario instalar el certificado de la CA en todos los dispositivos en los que queramos probar la aplicación, ya que está en la configuración del proyecto. Cabe destacar que como esta configuración se encuentra dentro del bloque debug-overrides, solo será válida cuando la aplicación se lance en modo debug, que es como Android Studio ejecuta las aplicaciones mientras estamos en fase de desarrollo.
Como se menciona anteriormente, el backend debe utilizar un keystore que incorpore tanto el certificado de la CA como el certificado cliente previamente firmado por dicha CA.
Para realizar el proceso de generación y firma de certificados, son necesarias las herramientas openssl y keytool. Los siguientes comandos pueden ser utilizados para realizar este proceso:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.
Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?
Pero espera 🖐 que tenemos un conflicto interno. A nosotros las newsletter nos parecen 💩👎👹 Por eso hemos creado la LEAN LISTA, la primera lista zen, disfrutona y que suena a rock y reggaeton del sector de la programación. Todos hemos recibido newsletters por encima de nuestras posibilidades 😅 por eso este es el compromiso de la Lean Lista