Noticia Cifrado de disco y protección de datos sensibles en Android

Cifrado de disco y protección de datos sensibles en Android


En el móvil llevamos hoy buena parte de nuestra vida: fotos personales, chats privados, documentación de trabajo, contraseñas guardadas, apps bancarias… Perder el teléfono o que alguien lo robe sin que los datos estén protegidos puede convertirse en un auténtico desastre, tanto a nivel personal como profesional, por eso conviene conocer medidas para reforzar la seguridad.

Para minimizar ese riesgo, Android incorpora desde hace años distintos mecanismos de cifrado que van mucho más allá del simple PIN o patrón de desbloqueo. El cifrado de disco y el cifrado basado en archivos, junto con el arranque verificado y las claves protegidas por hardware, forman un ecosistema complejo pensado para que, aunque alguien tenga el dispositivo en la mano, no pueda leer la información sin la credencial adecuada. Si necesitas hacerlo, consulta cómo cifrar tu móvil.

Qué es el cifrado de datos en Android y por qué importa tanto​


Cuando hablamos de cifrar un dispositivo Android nos referimos al proceso de transformar todos los datos almacenados en información ilegible si no se dispone de la clave correcta. A efectos prácticos, es como meter todo el contenido del móvil dentro de una caja fuerte digital que solo se abre con tu PIN, patrón, contraseña o factor biométrico.

Este cifrado protege tanto los datos de uso personal (fotos, vídeos, mensajes, archivos descargados) como los datos corporativos. En entornos de empresa es una pieza clave para cumplir con normativas como el RGPD europeo o HIPAA en EE. UU., ya que reduce enormemente el riesgo de fugas de información si se pierde o roba un terminal con información de clientes, historiales médicos, documentos legales o credenciales de acceso a VPN internas. Además, mantener copias de seguridad evita que la pérdida del dispositivo suponga la pérdida total de la información.

Conviene remarcar que el bloqueo de pantalla por sí solo no basta. Un PIN sin cifrado solo impide que alguien use el móvil desde la interfaz, pero si el almacenamiento no está cifrado, un atacante podría extraer físicamente los datos copiando el contenido de la memoria mediante herramientas forenses o vulnerabilidades del bootloader. Además, usar una app de seguridad Prey puede ayudar a localizar y gestionar un dispositivo perdido o robado, complementando el cifrado.

Con el cifrado activado, el almacenamiento se guarda en un formato matemáticamente incomprensible sin la clave. Aunque alguien copie byte a byte la partición de datos o arranque un sistema modificado, lo que obtendrá serán solo bloques de datos cifrados sin sentido.

De la encriptación de disco completo al cifrado basado en archivos​


Históricamente Android ha pasado por dos grandes enfoques de cifrado de dispositivo: cifrado de disco completo (FDE) y cifrado basado en archivos (FBE). Entender la diferencia ayuda mucho a comprender qué se protege en cada momento y por qué ciertas funciones siguen funcionando aunque el móvil esté “bloqueado”.

El cifrado de disco completo se introdujo en Android 4.4 (API 19), y ganó tracción real con Android 5.0 (API 21). En este modelo, toda la partición de datos de usuario se protege con una única clave. Esa clave se deriva de las credenciales del usuario, así que el sistema no puede acceder a nada de /data hasta que introduces tu PIN, patrón o contraseña al arrancar.

Este enfoque es muy robusto desde el punto de vista de la privacidad, pero tiene una desventaja clara: prácticamente todo el sistema queda inoperativo hasta que se desbloquea por primera vez tras el arranque. No hay acceso a alarmas, muchos servicios no se inician y el teléfono ni siquiera puede recibir llamadas normales, solo emergencias, porque la capa telefónica no tiene todavía acceso a sus datos.

Para solucionar ese problema, Google rediseñó todo el esquema de cifrado en Android 7.0 Nougat (API 24) introduciendo el cifrado basado en archivos (FBE). En este modelo, cada archivo puede estar protegido con una clave distinta, lo que permite que distintas partes del sistema se desbloqueen de forma independiente según qué credencial se haya proporcionado.

Con FBE llega además el llamado modo de Inicio o Arranque Directo (Direct Boot), que permite que el dispositivo arranque directamente hasta la pantalla de bloqueo y que algunas apps puedan funcionar en un contexto limitado antes de que el usuario introduzca su PIN o contraseña.

Cómo funciona el modo de Arranque Directo y la separación CE/DE​


El cambio conceptual clave de FBE es que, en un dispositivo con cifrado basado en archivos, cada usuario del sistema tiene dos zonas de almacenamiento diferenciadas, con claves distintas y momentos de desbloqueo diferentes.

La primera es el almacenamiento cifrado con credenciales (CE, Credential Encrypted). Es la ubicación de almacenamiento por defecto para los datos de usuario y aplicaciones, y solo se desbloquea después de que el usuario haya introducido sus credenciales tras un arranque. Ahí es donde deben guardarse todos los datos realmente sensibles: bases de datos de apps, documentos personales, copias locales de correos, etc.

La segunda es el almacenamiento cifrado por dispositivo (DE, Device Encrypted). Esta área está disponible tanto en el modo de Arranque Directo (antes de que el usuario se identifique) como después, y se cifra con una clave ligada al dispositivo que está disponible tan pronto como el sistema inicia correctamente. Es el área pensada para datos que deben estar accesibles incluso antes del primer desbloqueo: notificaciones básicas, servicios de telefonía, algunas funciones de accesibilidad, apps de alarma o el método de entrada de la pantalla de bloqueo.

Lo ideal es que, si una app necesita funcionar antes de que el usuario desbloquee el dispositivo (por ejemplo, un reloj despertador o el marcador telefónico), solo guarde en DE aquello estrictamente necesario para esa función básica, y mantenga en CE cualquier información personal o crítica.

De hecho, la recomendación de Google es clara: siempre que sea posible, los archivos deben residir en CE. El almacenamiento DE está pensado para configuraciones mínimas y datos efímeros, no para contenido sensible como listas de contactos completas, historiales de chat o documentos de empresa.

Requisitos técnicos y obligatoriedad del cifrado en Android moderno​


Desde Android 7.0 se permite FBE, y a partir de Android 10 Google obliga a que todos los dispositivos que salgan al mercado con esa versión o posterior usen cifrado basado en archivos. En teléfonos sin aceleración de cifrado AES por hardware, se emplea el algoritmo Adiantum para mantener un buen rendimiento.

Para implementar correctamente FBE, el fabricante debe cumplir varios requisitos de bajo nivel. Por un lado, el kernel de Linux del dispositivo tiene que soportar la capa de cifrado de sistemas de archivos fscrypt para ext4 o F2FS (las dos opciones habituales para /data en Android). En kernels modernos basta con activar opciones como CONFIG_FS_ENCRYPTION y, si se quiere aprovechar cifrado en línea, CONFIG_FS_ENCRYPTION_INLINE_CRYPT.

También es necesario contar con KeyMint o al menos Keymaster 1.0, y con Gatekeeper, ejecutándose dentro de un TEE (Trusted Execution Environment). De este modo, las claves de cifrado ligadas al dispositivo y al usuario quedan protegidas de sistemas operativos no autorizados y de kernels modificados que se intenten arrancar con el bootloader desbloqueado.

El dispositivo debe disponer además de una raíz de confianza de hardware y un arranque verificado que se vincule con la inicialización de KeyMint, para que un sistema no autorizado no pueda acceder a claves de cifrado de dispositivo (DE). Es decir, aunque se flashee un firmware modificado, la parte de hardware de seguridad se niega a entregar las claves si la cadena de arranque no es legítima.

A nivel de configuración, el cifrado FBE se habilita editando el fichero fstab del dispositivo para la partición userdata. Allí se especifica una opción fileencryption=… que define el algoritmo de cifrado de contenido (normalmente aes-256-xts o Adiantum), el algoritmo de nombres de archivos (aes-256-cts, aes-256-heh, aes-256-hctr2 o adiantum) y una serie de flags opcionales (v1/v2, inlinecrypt_optimized, emmc_optimized, wrappedkey_v0, dusize_4k).

Qué partes del sistema se cifran y cómo se organizan las claves​


En un sistema Android con FBE correctamente configurado, /data se organiza en distintas “clases de almacenamiento” en función de la clave que las protege y del momento en que quedan accesibles.

Existen directorios que no se cifran con FBE (aunque en muchos casos sí con cifrado de metadatos), como /data/apex (salvo algunos subdirectorios), /data/lost+found, /data/preloads o /data/unencrypted. Son rutas donde se almacenan componentes del sistema o estructuras que no necesitan vincularse a credenciales de usuario.

Luego está la clase de Sistema DE, que agrupa datos cifrados por dispositivo que no pertenecen a un usuario concreto: /data/app, /data/misc, /data/system, /data/vendor y otros subdirectorios de /data. También existe una clase “por inicio” (/data/per_boot) para archivos efímeros que no necesitan persistir entre reinicios.

Para cada usuario se crean a su vez rutas CE y DE específicas: /data/user/${user_id}, /data/system_ce/${user_id}, /data/misc_ce/${user_id}, /data/vendor_ce/${user_id} para CE interno; y /data/user_de/${user_id}, /data/system_de/${user_id}, /data/misc_de/${user_id}, /data/vendor_de/${user_id} para DE interno. Si hay almacenamiento adoptable (tarjeta SD transformada en extensión de la memoria interna), se replican estructuras similares bajo /mnt/expand/${volume_uuid}/.

La gestión de las claves corre a cargo de vold, el demonio de volúmenes de Android. Vold administra las claves de FBE y las almacena cifradas en disco (excepto la clave “por arranque”, que se deriva cada vez y no se guarda nunca). Por ejemplo, las claves CE y DE internas de usuario se guardan en /data/misc/vold/user_keys/ce/${user_id} y /data/misc/vold/user_keys/de/${user_id}, respectivamente, protegidas a su vez por claves almacenadas en Keystore dentro del TEE.

Salvo las claves CE de almacenamiento interno, el resto de claves FBE se envuelven con AES-256-GCM mediante claves de Keystore que no salen del entorno seguro. Además, se utilizan técnicas como resistencia a la reversión y archivos “secdiscardable” para asegurar que borrar una clave sea realmente definitivo incluso frente a intentos de restaurar estados antiguos del sistema.

Relación entre bloqueo de pantalla, contraseña sintética y claves CE​


Las claves CE de almacenamiento interno tienen un nivel de protección adicional, porque son las que realmente impiden que un atacante, incluso con control del sistema, pueda descifrar tus datos sin tu contraseña. Android introduce aquí el concepto de contraseña sintética: un secreto de alta entropía, generado aleatoriamente por el sistema para cada usuario, que nunca se introduce directamente, sino que se protege con el PIN, patrón o contraseña de bloqueo (LSKF).

El servicio LockSettingsService, en system_server, gestiona esa contraseña sintética. Cuando configuras o cambias tu PIN o contraseña de pantalla, el sistema toma esa LSKF, la pasa por scrypt (para endurecerla algo) y la usa para interactuar con Weaver o Gatekeeper, según el hardware del dispositivo.

En dispositivos con Weaver, la LSKF endurecida se asocia a un secreto aleatorio de alta entropía guardado en un elemento seguro (SE) o en el TEE. Luego, la contraseña sintética se cifra dos veces: primero con una clave derivada de la LSKF + secreto Weaver, y después con una clave de Keystore. Eso introduce un límite de velocidad de intentos aplicado por hardware para adivinar la contraseña, evitando ataques de fuerza bruta rápidos.

En dispositivos sin Weaver, la LSKF endurecida se usa con Gatekeeper, y de nuevo la contraseña sintética se cifra primero con una clave derivada de la LSKF y un archivo descartable, y luego con una clave de Keystore ligada a la autenticación en Gatekeeper. El resultado es que las claves CE no se pueden desbloquear sin superar esas protecciones, aunque se intente con un sistema modificado o con un arranque alternativo.

Cuando cambias el PIN o la contraseña de bloqueo, LockSettingsService elimina la vinculación anterior entre LSKF y contraseña sintética. En dispositivos con soporte de resistencia a la reversión, eso hace que no se puedan reutilizar antiguas asociaciones, reforzando aún más el modelo de seguridad.

¿Sigue protegido el cifrado con bootloader desbloqueado o root?​


Cifrado de disco y protección de datos sensibles en Android


Aquí entra uno de los puntos que generan más debate entre usuarios avanzados. En teoría, un sistema de cifrado “bien diseñado” no debería romperse solo porque el bootloader esté desbloqueado o porque consigas un shell ADB con privilegios de root: mientras no dispongas de la clave derivada de la contraseña del usuario, los datos deberían seguir siendo ilegibles.

En la práctica, el modelo de Android moderno busca dos cosas: por un lado, que sin la LSKF no se puedan obtener las claves CE, gracias al uso conjunto de TEE/SE, Gatekeeper/Weaver y Keystore; por otro, que el arranque verificado bloquee el acceso a claves DE si se detecta un sistema no confiable. Sin embargo, hay matices importantes.

Uno de ellos es que, en dispositivos con FBE, parte del contenido de /data puede estar disponible en DE incluso antes de introducir el PIN. Eso incluye estructuras internas, ficheros auxiliares e incluso ciertos directorios en /data/misc, /data/system o similares que, aunque sí estén cifrados en disco, se descifran tras el arranque porque la clave DE está disponible sin interacción del usuario.

En algunos experimentos reales se ha observado, por ejemplo, que en un Moto X4 con LineageOS 16 (Android 9), FBE activo y SD adoptada, /data ya aparece montado al llegar a la pantalla de bloqueo, y desde un shell ADB root se pueden extraer algunos archivos concretos sin haber introducido la contraseña. Otros, en cambio, fallan o parecen inaccesibles, lo que indicaría que están correctamente ligados a CE.

Más grave todavía es que, si los permisos y políticas no están bien ajustados, puede llegarse a leer desde /data/misc/vold ciertas claves asociadas a volúmenes adoptables, como la de la tarjeta SD cifrada. Con esa clave, es posible montar y descifrar el volumen fuera del teléfono, dejando el cifrado de la tarjeta en papel mojado.

Este tipo de situaciones no son tanto un fallo del diseño de FBE en sí, sino errores de implementación o configuraciones inseguras en ROMs personalizadas, recoveries modificados o dispositivos en los que el fabricante no ha seguido todas las recomendaciones (por ejemplo, no aislar bien quién puede acceder a /data/misc/vold, no aplicar SELinux en modo estricto o no separar adecuadamente los datos que deben ir en CE). Revisar y ajustar los ajustes de seguridad ayuda a reducir estos riesgos.

Por qué Spotify, YouTube o las notificaciones siguen funcionando con el móvil bloqueado​


Una duda muy común entre los usuarios es: si “todo está cifrado” cuando bloqueo el móvil, ¿cómo es que siguen sonando las notificaciones, funciona Spotify o se reciben mensajes mientras la pantalla está apagada y aparentemente el dispositivo está protegido?

La clave está en el modelo FBE y en la distinción entre estado de bloqueo de pantalla y estado de desbloqueo de almacenamiento. Tras el primer desbloqueo después del arranque, la mayoría de claves CE permanecen disponibles mientras el dispositivo no se reinicie. Bloquear la pantalla no vuelve a cifrar todo desde cero, simplemente cierra el acceso lógico a la interfaz y a ciertas APIs, pero el sistema sigue teniendo las claves en memoria para poder operar.

Además, muchos de los datos que necesitan apps como Spotify, YouTube o los servicios de notificaciones push se guardan o replican en zonas DE, o bien las apps se marcan como “directBootAware” para poder funcionar con un subconjunto limitado de datos mientras el usuario aún no ha introducido el PIN tras un reinicio. Por eso puedes, por ejemplo, recibir una llamada o sonar una alarma incluso si el teléfono se acaba de encender y todavía estás en la pantalla de bloqueo inicial.

El descifrado no toma literalmente “1 segundo”; lo que ocurre es que ya se realizó el trabajo pesado en el arranque y en el primer desbloqueo. A partir de ahí, el sistema mantiene las claves activas (hasta el próximo reinicio) para no tener que recalcularlo todo continuamente, lo que haría la experiencia de uso insoportable.

Esto implica que, si un atacante obtiene privilegios elevados una vez que el dispositivo ya se ha desbloqueado después de un arranque (por ejemplo, mediante malware con root o un exploit de kernel), podría acceder a mucha más información que si trata de hacerlo justo tras encender el dispositivo, antes de que nadie ponga el PIN. De ahí que sea tan importante reiniciar forzosamente un dispositivo antes de entregarlo a controles fronterizos, técnicos de reparación u otras situaciones sensibles y no desbloquearlo de nuevo.

Qué pueden y qué no pueden hacer las apps del sistema con Direct Boot​


Con la llegada de FBE, Android introdujo nuevas APIs y atributos de manifiesto para que las apps sepan en qué estado de cifrado se encuentra el dispositivo y qué almacenamiento tienen disponible en cada momento.

En el manifiesto de una app se pueden declarar dos atributos relevantes: android:directBootAware y android:defaultToDeviceProtectedStorage. El primero indica que todos los componentes de la app son conscientes del cifrado y pueden funcionar durante el modo de Arranque Directo; el segundo hace que la app, por defecto, use el almacenamiento DE en lugar del CE para sus datos.

Las apps del sistema que se marcan con defaultToDeviceProtectedStorage deben auditar cuidadosamente qué información guardan en esa ubicación y mover a CE cualquier dato que pueda considerarse personal o sensible. Aquí los fabricantes tienen la responsabilidad de no volcar historiales extensos, listas de contactos o datos de usuario en DE, sino limitarse a configuraciones mínimas necesarias para que el dispositivo sea funcional antes del primer desbloqueo.

Para manejar mejor estos contextos, Android proporciona métodos como Context.createCredentialProtectedStorageContext() y Context.isCredentialProtectedStorage(), que permiten a las apps elegir explícitamente dónde guardar o leer sus datos según el estado de cifrado y las necesidades de privacidad.

En dispositivos multiusuario y con perfiles de trabajo, la cosa se complica aún más: cada usuario y cada perfil de trabajo tienen sus propias claves CE y DE. Permisos de aplicaciones como INTERACT_ACROSS_USERS o INTERACT_ACROSS_USERS_FULL permiten a ciertas apps del sistema actuar entre usuarios, pero solo pueden acceder al CE de aquellos que ya estén desbloqueados, lo que añade otra capa de aislamiento.

Cifrado de la tarjeta SD y almacenamiento adoptable: fortalezas y agujeros​


Cuando usas una tarjeta SD como almacenamiento adoptable, Android la trata como una extensión cifrada de la memoria interna. La tarjeta se cifra con una clave que, en principio, solo el propio dispositivo debería poder usar, y esa clave se almacena cifrada junto con otras claves de volumen bajo rutas como /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} o /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid}.

Desde Android 9, el FBE y el almacenamiento adoptable ya son totalmente compatibles, y a partir de Android 11 se unifica la forma de definir formatos de cifrado de contenido y de metadatos mediante propiedades de sistema como ro.crypto.volume.options o ro.crypto.volume.metadata.encryption. En versiones anteriores se usaban propiedades separadas para modos de contenido y nombres de archivo, y en muchos dispositivos el valor por defecto para nombres en volúmenes adoptables era poco recomendable, por lo que debía ajustarse expresamente.

En un mundo ideal, aunque alguien saque la tarjeta SD, los datos deberían seguir inaccesibles sin la clave almacenada en el teléfono. Pero, de nuevo, si esa clave se puede extraer de /data/misc/vold con un shell root porque el dispositivo está mal configurado, el modelo se derrumba. Esto demuestra por qué no basta con “activar cifrado” a nivel teórico: hay que acompañarlo de buenas políticas SELinux y de un diseño cuidadoso de los permisos.

Para tarjetas SD usadas como almacenamiento externo tradicional (no adoptable), muchos fabricantes ofrecen una opción de “cifrar tarjeta SD” desde Ajustes > Seguridad. Normalmente ese cifrado hace que solo ese dispositivo concreto pueda leer lo que hay en la tarjeta. El proceso puede tardar más o menos según el tamaño y la velocidad de la SD, pero una vez completado, si insertas la tarjeta en otro teléfono u ordenador, el contenido aparecerá como ilegible. Como complemento a esto, conviene mantener también copias de seguridad en la nube para garantizar que la información no se pierde si la tarjeta falla.

Aun así, si el enfoque de claves no está bien atado, extraer la clave de la SD desde el propio teléfono podría permitir descifrarla externamente. Por eso, en contextos de alta seguridad, muchas empresas recomiendan no usar SD adoptables o limitar su uso solo a datos no críticos.

Cifrado, rendimiento y posibles inconvenientes​


El cifrado tiene un coste computacional: leer o escribir datos cifrados implica operar con algoritmos como AES-256-XTS o Adiantum. En dispositivos modernos con aceleración criptográfica por hardware (por ejemplo, extensiones ARMv8 CE en ARM64), el impacto en rendimiento y consumo es muy pequeño y casi imperceptible.

Para exprimir al máximo el rendimiento, los kernels comunes de Android incluyen un framework de cifrado intercalado (inline encryption), que permite que determinados controladores de almacenamiento (UFS, eMMC) cifren y descifren datos “en vuelo”. Activar opciones como CONFIG_BLK_INLINE_ENCRYPTION, CONFIG_SCSI_UFS_CRYPTO o CONFIG_MMC_CRYPTO, junto con flags como inlinecrypt_optimized o emmc_optimized, ayuda a minimizar la sobrecarga y extender la batería.

En dispositivos antiguos o sin soporte AES acelerado, la penalización puede notarse más, de ahí que Google diseñara Adiantum, un esquema pensado para ofrecer seguridad fuerte en hardware modesto. Aun así, algunos usuarios pueden percibir cierta bajada de rendimiento, sobre todo si el cifrado se activa manualmente en un terminal de gama baja.

Otro punto a tener presente es que, una vez se cifra el almacenamiento, no suele haber marcha atrás sin restaurar de fábrica. El formato de cifrado en disco viene definido por opciones como fileencryption en fstab y no se puede cambiar con una simple actualización OTA. Si se quiere desactivar el cifrado, la solución típica pasa por borrar la partición de datos y empezar de cero.

En versiones antiguas de Android, algunas OTAs tradicionales requerían acceso desde la partición recovery a datos ubicados en /data, lo que no es posible si esa zona está protegida por DE. En esos casos, ciertos fabricantes optaron por dejar un directorio de nivel superior sin cifrar (por ejemplo, /data/misc_ne) exclusivamente para guardar paquetes de actualización, controlando con SELinux que solo el proceso de actualización pudiera acceder a ellos.

Más allá de estas consideraciones técnicas, para el usuario de a pie el principal “inconveniente” del cifrado es que, si olvida su PIN o contraseña y no tiene mecanismos de recuperación, la información se pierde para siempre. No existe puerta trasera oficial: sin la LSKF y sin poder derivar la contraseña sintética, las claves CE no se recuperan.

Al final, todo este entramado hace que el cifrado de disco y la protección de datos sensibles en Android sean mucho más sofisticados de lo que parece a simple vista. Entre FDE y FBE, los espacios CE y DE, el TEE, KeyMint, Gatekeeper, fscrypt, el cifrado de metadatos y el arranque verificado, el sistema está pensado para que un atacante no autorizado, aunque tenga el dispositivo en sus manos e intente arrancar software modificado o usar ADB con root, lo tenga extremadamente difícil para leer algo útil sin la contraseña del usuario, siempre que el fabricante haya seguido las recomendaciones y el usuario complemente con un bloqueo fuerte, actualizaciones al día y sentido común al instalar aplicaciones.

Continúar leyendo...