Esquema de firma de APK v3.1

Android 13 admite el esquema de firma de APK v3.1, una mejora del esquema de firma de APK v3 existente. El esquema v3.1 aborda algunos de los problemas conocidos con el esquema de firma de APK v3 en relación con la rotación. En particular, el esquema de firma v3.1 admite la segmentación por versión del SDK, lo que permite que la rotación se dirija a una versión posterior de la plataforma.

El esquema de firma v3.1 usa un ID de bloque que no se reconoce en Android 12 ni versiones anteriores. Por lo tanto, la plataforma aplica el siguiente comportamiento del firmante:

  • Los dispositivos que ejecutan Android 13 o versiones posteriores usan el firmante rotado en el bloque v3.1.
  • Los dispositivos que ejecutan versiones anteriores de Android ignoran el firmante rotado y, en su lugar, usan el original en el bloque v3.

Las apps que aún no rotaron su clave de firma no requieren ninguna acción adicional. Cada vez que estas apps elijan rotar, el sistema aplicará el esquema de firma v3.1 de forma predeterminada.

Bloque de firma v3.1

El bloque de firma v3.1 tiene el mismo contenido que el bloque de firma v3, pero, con el nuevo ID de bloque, estas firmas solo se reconocen en dispositivos que ejecutan Android 13 y versiones posteriores. Esto permite que las apps roten sus claves de firma de forma segura sin tener que preocuparse por los APKs de múltiples destinos, ya que el firmante original se puede usar para firmar el APK en el bloque de firma v3 y el firmante rotado en el bloque de firma v3.1. Esto también permite que la plataforma reutilice todos los códigos de verificación existentes para el bloque de firma de la versión 3 cuando se verifica una firma de la versión 3.1.

De forma predeterminada, la biblioteca apksig usa el bloque de firma v3.1 siempre que se proporcionen una clave rotada y un linaje en la configuración de firma. Si el minSdkVersion de una app es inferior a Android 12 y se usa una clave rotada, también se debe especificar la clave de firma original para que se pueda usar para firmar el APK en el bloque de firma v3. Esto es similar al comportamiento actual, en el que se requiere el firmante original si el APK se segmenta para una versión anterior a Android 9.

Para admitir la rotación de claves de segmentación a partir de una versión de SDK en particular, la biblioteca apksig expone nuevas APIs que permiten establecer una versión mínima del SDK para la rotación. Si se especifica una versión del SDK anterior a Android 12 como la versión mínima para la compatibilidad con la rotación, se usa el bloque v3 original. El bloque de firma v3.1 solo se usa en presencia de rotación cuando la versión mínima del SDK para la rotación se establece en Android 12 y versiones posteriores. El bloque de firma v3 tiene un atributo para la protección contra la eliminación de la versión mínima del SDK de rotación.

El APK incluye linaje Valor de rotation-min-sdk-version Bloque de firma de la versión 3 Bloque de firma de v3.1
No Valor predeterminado o cualquier valor (representado por x a continuación) Firmado con el firmante original, orientado a Android 9 y versiones posteriores Ausente
Predeterminado Firmado con el firmante original, con orientación a Android 9 a 12L Firmada con el firmante rotado y orientada a Android 12 y versiones posteriores
x < 33 (Android 13) Firmada con un firmante rotado y orientada a Android 9 y versiones posteriores Ausente
x >= 33 (Android 13) Firmado con el firmante original, segmentado para Android 9 (x-1) Firmado con el firmante rotado, segmentación para x+

Problemas relacionados con la rotación

Se resolvieron los siguientes problemas relacionados con la rotación en la plataforma:

Correcciones en Android 12

  • La plataforma solo otorgaría un permiso de firma a una app solicitante si el firmante actual de cualquiera de las apps está en el linaje de firmas o es el firmante actual de la otra app. Esto evita otorgar un permiso de firma a una app solicitante si las dos apps siguen las prácticas recomendadas de claves de firma y rotan a diferentes claves de firma.
  • La función de reversión de APK de la plataforma no podía revertir un APK cuya clave de firma se acababa de rotar, a menos que la clave anterior en el linaje de firma tuviera la capacidad de reversión, pero esta capacidad anula el propósito de la rotación, ya que permite que una actualización de paquete nueva se firme con la clave de firma anterior y se revierta la clave rotada.
  • Un APK firmado solo con la clave rotada y, luego, actualizado con un APK firmado con la clave original y la clave rotada en el linaje solo muestra la clave rotada en el linaje en dispositivos que ejecutan Android 11 y versiones anteriores.

Correcciones de Android 11

  • PackageManager#checkSignatures no se actualizó correctamente para verificar las claves de firma originales de dos paquetes. Esto interrumpió la instrumentación de las apps que usan una clave de firma rotada con el APK de instrumentación que usa la clave de firma original.
  • Los paquetes de un sharedUserId comparten su linaje de firma. Cada vez que se instala o actualiza una app con un linaje de firma actualizado en un sharedUiserId, el linaje de esa app reemplaza el linaje compartido del sharedUserId (es decir, si el linaje de firma de una app fuera A -> B y se actualizara una app en el sharedUserId con el linaje B -> C, el linaje del sharedUserId se reemplazaría por B -> C). Del mismo modo, no se podían actualizar las capacidades de un firmante anterior en el linaje, a menos que se cambiara el linaje de firma.

Integración de la versión 4

El esquema de firma v4 usa la configuración de firma proporcionada a apksigner. En el caso de que se proporcionen varias configuraciones de firma para la rotación, se usa la configuración de firma rotada más reciente. Antes de la introducción de la versión 3.1, la versión 3 solo incluía esta configuración de firma rotada más reciente, por lo que la versión 4 pudo usar esta configuración tal como estaba. Con esto, el esquema de firmas de la versión 4 pudo admitir la rotación, ya que usaba la clave de firma rotada en su SigningInfo. Si bien SigningInfo de la versión 4 no incluye el linaje de firma completo, puede extraerlo del bloque de firma de la versión 3 para permitir que la plataforma acceda al linaje para cualquier consulta de firma. Cuando se usa la versión 3.1 para la rotación de destino para la versión mínima del SDK de rotación proporcionada, la configuración genérica de la versión 3 incluye la configuración de firma original y la configuración de firma rotada más reciente. Se creó una extensión del esquema de firma v4 que incluye bloques de información de firma adicionales para cada una de las configuraciones de firma del bloque v3.1.

Validación

Para probar tu implementación de la versión 3.1, ejecuta las pruebas de PkgInstallSignatureVerificationTest.java CTS en cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.

Para obtener más información sobre las pruebas, consulta la sección de verificación en la versión 3.