Esquema de firma de APK v3.2

Android 17 (nivel de API 37) presenta el esquema de firma de APK v3.2, un esquema de firma híbrido diseñado para admitir la transición del ecosistema de Android a la criptografía poscuántica (PQC).

A medida que la industria implementa algoritmos de PQC a gran escala, el esquema v3.2 proporciona defensa en profundidad. Requiere que firmes los APK con un algoritmo clásico, como RSA o ECDSA, y un algoritmo de PQC. Este enfoque híbrido usa criptografía clásica para proteger tu APK mientras te defiendes de las amenazas de las computadoras cuánticas.

Propósito y detalles

El esquema v3.2 funciona como un mecanismo de transición estándar y alineado con la industria. Con este enfoque híbrido, obtienes los beneficios resistentes a la cuántica de la PQC mientras sigues confiando en la seguridad comprobada de los algoritmos de firma clásicos. Una vez que los algoritmos de PQC recién estandarizados establezcan la madurez operativa a gran escala, podrás realizar la transición de esta configuración híbrida a una sola clave de firma de PQC. La compatibilidad de la plataforma con el esquema de firma v3.2 comienza con Android 17. Las versiones anteriores de Android omiten el bloque v3.2 y usan esquemas anteriores para la verificación de firmas.

Para mantener la seguridad y evitar ataques de degradación durante esta transición, el esquema v3.2 aplica los siguientes comportamientos:

  • Material de clave nuevo: La transición a un bloque híbrido requiere la generación de claves clásicas y de PQC nuevas. No vuelvas a usar material de clave entre configuraciones híbridas y no híbridas.
  • Rotación implícita: La plataforma trata el bloque híbrido como una rotación de claves implícita. La plataforma agrega la nueva clave clásica al linaje de firmas existente de la app como la penúltima clave y trata la nueva clave de PQC como la identidad de firma actual de la app.
  • Linaje compartido: Para ejecutar correctamente la rotación implícita, tanto la nueva clave clásica como la nueva clave de PQC dentro del bloque híbrido deben compartir el mismo linaje de firmas. Debes duplicar el historial de firmas existente de la app, ya sea una sola clave original o un linaje de claves rotadas anteriormente, para ambos firmantes híbridos nuevos. La plataforma usa este linaje compartido para verificar que la entidad que realiza la transición de la app al esquema híbrido sea el propietario legítimo de la identidad de firma actual de la app.
  • Restricción de firmante único de PQC: Durante el lanzamiento inicial de PQC, Android restringe explícitamente el uso de algoritmos de PQC al bloque híbrido v3.2. La plataforma no verifica una configuración de PQC de firmante único con esquemas de firma anteriores, como v2, v3.0 o v3.1.
  • Transición de regreso: Cuando se realiza la transición de un bloque híbrido v3.2 a un bloque de firmante único, ya sea un firmante clásico o un firmante de PQC cuando se admita en una versión futura, la plataforma verifica que las claves clásicas y de PQC del bloque híbrido estén presentes en el nuevo linaje de firmas y den fe del nuevo firmante único.

Prácticas recomendadas para la transición

Para mantener la compatibilidad con versiones anteriores de Android y proporcionar una ruta de actualización segura durante la transición a la firma de PQC, los APK deben seguir incluyendo un bloque de firma v3.0 o v3.1 estándar firmado por una sola clave clásica. Debido a que solo Android 17 (nivel de API 37) y versiones posteriores admiten el esquema híbrido v3.2, este requisito permite que los dispositivos que ejecutan versiones anteriores verifiquen e instalen la app.

Configuración de resguardo clásica

Para proporcionar una red de seguridad operativa durante la transición de PQC, implementa una configuración de resguardo clásica.

  • Apps existentes: La clave de firma establecida actual de la app, K0, sirve como base natural para este resguardo.
  • Apps nuevas: Genera una clave de firma clásica de referencia, K0, junto con las nuevas claves híbridas, C_K1 y PQC_K1, para establecer la identidad inicial.

En ambos casos, el APK debe incluir un bloque de firma v3.0 o v3.1 estándar firmado por la clave clásica, K0, junto con el bloque híbrido v3.2 firmado por las nuevas claves híbridas, C_K1 y PQC_K1.

Durante la implementación inicial del esquema v3.2, el linaje de firmas del bloque híbrido debe otorgar la capacidad ROLLBACK a K0. Si surgen problemas de implementación, esta capacidad permite que la app vuelva a una firma clásica sin interrumpir las actualizaciones del usuario. Una vez que los datos de tiempo de ejecución suficientes confirmen que la implementación híbrida es estable, te recomendamos que quites la capacidad ROLLBACK en las actualizaciones posteriores para proteger por completo tus claves nuevas.

Requisitos de configuración a largo plazo

Debes mantener esta configuración de firma híbrida mientras tu app se oriente a una versión de la plataforma que admita exclusivamente el esquema híbrido. Incluso si una versión de la plataforma admite claves de PQC de firmante único, debes firmar cualquier APK que se oriente a una versión que requiera el bloque híbrido v3.2 con ambas claves.

Bloque del esquema de firma de APK v3.2

El bloque de firma de APK almacena el bloque de firma v3.2 junto con los bloques de firma v2, v3.0 y v3.1.

La estructura del bloque v3.2 es similar a la de v3.0, pero usa un nuevo ID de bloque, 0x70e1c89f, para indicar que es un bloque híbrido. Un bloque v3.2 válido debe contener exactamente dos firmantes.

Algoritmos compatibles

Inicialmente, el esquema v3.2 admite los siguientes algoritmos de firma de PQC:

  • ML-DSA-65
  • ML-DSA-87

Estos se combinan con algoritmos de firma clásicos estándar, como los que se admiten en v3.0 y v3.1, para formar el bloque híbrido.

Formato

El bloque de firma de APK almacena el bloque del esquema de firma de APK v3.2 con el ID 0x70e1c89f.

El formato del bloque v3.2 es idéntico a v3.0, pero la secuencia de nivel superior de los elementos de firmante debe contener exactamente dos entradas orientadas a la misma versión del SDK:

  • length-prefixed sequence of length-prefixed signer:
    • length-prefixed signer (Classical)
    • length-prefixed signer (PQC)

Cada firmante usa el formato v3 estándar:

  • length-prefixed signed data:
    • length-prefixed sequence of length-prefixed digests:
    • signature algorithm ID (4 bytes)
    • digest (length-prefixed)
    • length-prefixed sequence of certificates:
    • length-prefixed X.509 certificate (ASN.1 DER form)
    • minSDK (uint32)
    • maxSDK (uint32)
    • length-prefixed sequence of length-prefixed additional attributes:
    • ID (uint32)
    • value (variable-length: length of the additional attribute - 4 bytes)
  • minSDK (uint32)
  • maxSDK (uint32)
  • length-prefixed sequence of length-prefixed signatures:
    • signature algorithm ID (4 bytes)
    • length-prefixed signature over signed data
  • length-prefixed public key (SubjectPublicKeyInfo, ASN.1 DER form)

Verificación

En Android 17 (nivel de API 37) y versiones posteriores, para verificar la firma v3.2, la plataforma verifica los firmantes clásicos y de PQC, confirma su compatibilidad y verifica el linaje de rotación implícito. En Android 16 (nivel de API 36) y versiones anteriores de la plataforma, la plataforma no procesa este bloque de firma híbrido y, en su lugar, usa esquemas anteriores.

El proceso general es el siguiente:

  1. Busca el bloque del esquema de firma de APK v3.2 (ID 0x70e1c89f).
  2. Verifica que el bloque contenga exactamente dos firmantes. Si hay menos o más de dos, la verificación falla.
  3. Verifica que un firmante use un algoritmo de firma clásico y el otro use un algoritmo de firma de PQC. Si ambos son clásicos o ambos son de PQC, la verificación falla.
  4. Verifica que ambos firmantes se orienten al mismo rango de SDK (minSdkVersion y maxSdkVersion).
  5. Para cada uno de los dos firmantes, realiza la verificación v3 estándar:
    1. Elige el ID de algoritmo de firma compatible más potente de las firmas.
    2. Verifica la firma correspondiente de las firmas con los datos firmados usando la clave pública.
    3. Verifica que minSdkVersion y maxSdkVersion en los datos firmados coincidan con minSdkVersion y maxSdkVersion sin firmar.
    4. Analiza los certificados y verifica que el primer certificado coincida con la clave pública.
    5. Analiza los atributos adicionales para extraer estructuras de prueba de rotación.
  6. Verifica el historial de firmas (prueba de rotación):
    1. Comprueba que ambos firmantes tengan historiales de firmas anteriores idénticos.
    2. Las longitudes del linaje deben coincidir, y todos los certificados y marcas de capacidad que conducen a los firmantes actuales deben ser idénticos.
    3. Si los historiales coinciden, une los linajes: trata el certificado del firmante clásico como el predecesor del certificado del firmante de PQC y asigna el firmante de PQC como el nodo terminal actual.
  7. Verifica los resúmenes de contenido:
    1. Itera a través del mapa de resúmenes para ambos firmantes.
    2. Verifica que, para cualquier algoritmo de resumen coincidente, los valores de resumen calculados sean idénticos entre los firmantes clásicos y de PQC.
  8. Usa los resúmenes coincidentes de los firmantes verificados para verificar la integridad del contenido del APK (similar a v2 y v3).
    1. Si la app ya está instalada, verifica el linaje de actualización del paquete:
    2. Actualización desde un solo firmante: Si la app instalada se firmó con una sola clave clásica, esa clave debe estar presente en el linaje de firmas del nuevo bloque híbrido como predecesor de los firmantes híbridos.
    3. Actualización de un firmante híbrido para continuar con el híbrido: Si la app instalada se firmó con un bloque híbrido v3.2, las claves clásicas y de PQC anteriores deben seguir siendo los firmantes activos actuales en el bloque v3.2 del APK de actualización, o bien deben estar presentes en el nuevo linaje de firmas que da fe de las claves híbridas recién rotadas.
    4. Transición desde un firmante híbrido: Si la app instalada se firmó con un bloque híbrido v3.2 y el APK de actualización vuelve a un solo firmante (ya sea PQC o clásico), ambos firmantes híbridos anteriores deben estar presentes en el linaje de firmas del APK de actualización y dar fe de la nueva clave de firma única.
    5. Rutas de actualización no válidas: Si un desarrollador intenta actualizar una app firmada de forma híbrida usando solo una de las claves híbridas como un solo firmante sin una rotación adecuada, la actualización falla. Ambas claves deben participar explícitamente en cualquier transición para evitar ataques de degradación.
  9. Si falla algún paso, la verificación falla.

Protección contra la eliminación

Para evitar ataques de degradación a esquemas de firma inferiores, el esquema v3.2 incluye atributos de protección contra la eliminación similares a las iteraciones de esquemas anteriores.

La herramienta de firma escribe dos atributos específicos de protección contra la eliminación híbrida en los atributos adicionales de los bloques de firma v3.0 y v3.1. Estos atributos definen los límites exactos de la versión del SDK dentro de los cuales debe estar presente y verificarse el bloque híbrido v3.2:

  • Atributo de versión mínima del SDK (ID 0xbf940529): El valor de este atributo dicta la versión mínima del SDK que admite el bloque de firma híbrido.
  • Atributo de versión máxima del SDK (ID 0x9f06b79c): El valor de este atributo dicta la versión máxima del SDK que admite el bloque de firma híbrido. Este atributo te permite realizar la transición a una configuración de firmante único cuando las versiones más recientes de la plataforma no requieren la firma híbrida.

Si la plataforma omite la verificación v3.2 porque falta el bloque o su rango de SDK no se aplica al dispositivo, la plataforma verifica el APK con el siguiente bloque presente. Si ese bloque anterior contiene estos atributos de protección contra la eliminación, la plataforma aplica las siguientes verificaciones:

  • Verificación de presencia y rango: Si un bloque de firma v3.0 o v3.1 contiene el atributo de SDK mínimo (ID 0xbf940529, valor X) o el atributo de SDK máximo (ID 0x9f06b79c, valor Y), la plataforma requiere que el bloque híbrido v3.2 exista dentro del APK. La plataforma lee el bloque híbrido para verificar que su rango de SDK objetivo coincida con los límites especificados por estos atributos. Si falta el bloque v3.2 o si sus valores internos de destino de SDK mínimo y máximo no son iguales a X y Y, la plataforma rechaza la instalación.
  • Aplicación dentro del rango: Si la versión del SDK del dispositivo se encuentra dentro del rango válido especificado por estos atributos, que es mayor o igual que X y menor o igual que Y cuando proporcionas el atributo máximo, la plataforma requiere estrictamente el bloque híbrido v3.2 para la verificación de firmas. Si la plataforma verifica un bloque v3.0 o v3.1 en un dispositivo dentro de este rango de SDK objetivo, la plataforma rechaza la instalación porque el bloque v3.2 se omitió o se eliminó de forma maliciosa.

Al aplicar estos límites, la plataforma determina cuándo un APK debe contener un bloque v3.2. Si se eliminó el bloque, la plataforma rechaza la instalación para evitar un ataque de degradación.

Valida la implementación

Para probar tu implementación del esquema de firma v3.2, ejecuta las pruebas CTS HybridSignatureVerificationTest.java ubicadas en cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.

Estas pruebas abarcan un conjunto integral de situaciones, incluidas las instalaciones exitosas, las actualizaciones de versiones solo clásicas, las transiciones de reversión con la capacidad ROLLBACK y las verificaciones de mitigaciones de ataques de eliminación.