Google se compromete a promover la equidad racial para las comunidades negras. Ver cómo.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Esquema de firma APK v3

Android 9 admite la rotación de claves APK , lo que brinda a las aplicaciones la capacidad de cambiar su clave de firma como parte de una actualización de APK. Para que la rotación sea práctica, los APK deben indicar niveles de confianza entre la clave de firma nueva y la antigua. Para admitir la rotación de claves, actualizamos el esquema de firma APK de v2 a v3 para permitir que se usen las claves nuevas y antiguas. V3 agrega información sobre las versiones de SDK compatibles y una estructura de prueba de rotación al bloque de firma de APK.

Bloque de firma de APK

Para mantener la compatibilidad con el formato APK v1, las firmas APK v2 y v3 se almacenan dentro de un bloque de firma APK, ubicado inmediatamente antes del directorio central de ZIP.

El formato del Bloque de firma APK v3 es el mismo que v2 . La firma v3 de la APK se almacena como un par ID-valor con ID 0xf05368c0.

Bloque de firma APK v3 Block

El esquema v3 está diseñado para ser muy similar al esquema v2 . Tiene el mismo formato general y admite las mismas ID de algoritmo de firma , tamaños de clave y curvas EC.

Sin embargo, el esquema v3 agrega información sobre las versiones de SDK compatibles y la estructura de prueba de rotación.

Formato

APK Signature Scheme v3 Block se almacena dentro del APK Signing Block con el ID 0xf05368c0 .

El formato del bloque APK Signature Scheme v3 sigue el de v2:

  • secuencia con prefijo de longitud del signer prefijo de longitud:
    • signed data prefijo de longitud:
      • secuencia de longitud prefijada de longitud prefijada digests :
        • signature algorithm ID (4 bytes)
        • digest (con prefijo de longitud)
      • secuencia de prefijos de longitud de certificates X.509:
        • certificate X.509 con prefijo de longitud (formulario DER ASN.1)
      • minSDK (uint32): este firmante debe ignorarse si la versión de la plataforma está por debajo de este número.
      • maxSDK (uint32): este firmante debe ignorarse si la versión de la plataforma está por encima de este número.
      • secuencia con prefijo de longitud de additional attributes prefijo de longitud:
        • ID (uint32)
        • value (longitud variable: longitud del atributo adicional - 4 bytes)
        • ID - 0x3ba06f8c
        • value - Estructura de prueba de rotación
    • minSDK (uint32): duplicado del valor de minSDK en la sección de datos firmados, utilizado para omitir la verificación de esta firma si la plataforma actual no está dentro del rango. Debe coincidir con el valor de los datos firmados.
    • maxSDK (uint32): duplicado del valor de maxSDK en la sección de datos firmados, utilizado para omitir la verificación de esta firma si la plataforma actual no está dentro del rango. Debe coincidir con el valor de los datos firmados.
    • secuencia con prefijo de longitud de signatures prefijo de longitud:
      • signature algorithm ID (uint32)
      • signature con prefijo de longitud sobre signed data
    • public key prefijo de longitud (SubjectPublicKeyInfo, formulario DER ASN.1)

Estructuras de prueba de rotación y confianza de viejos certificados

La estructura de prueba de rotación permite a las aplicaciones rotar su certificado de firma sin ser bloqueadas en otras aplicaciones con las que se comunican. Para lograr esto, las firmas de la aplicación contienen dos nuevos datos:

  • afirmación para terceros de que se puede confiar en el certificado de firma de la aplicación donde sea que se confíe en sus predecesores
  • certificados de firma más antiguos de la aplicación en los que la aplicación todavía confía

El atributo de prueba de rotación en la sección de datos firmados consiste en una lista enlazada individualmente, con cada nodo que contiene un certificado de firma utilizado para firmar versiones anteriores de la aplicación. Este atributo está destinado a contener las estructuras de datos conceptuales de prueba de rotación y de confianza de los viejos certificados. La lista está ordenada por versión con el certificado de firma más antiguo correspondiente al nodo raíz. La estructura de datos de prueba de rotación se construye haciendo que el certificado en cada nodo firme el siguiente en la lista y, por lo tanto, imbuya a cada nueva clave con evidencia de que debe ser tan confiable como las claves más antiguas.

La estructura de datos self-Trusted-old-certs se construye agregando banderas a cada nodo que indican su pertenencia y propiedades en el conjunto. Por ejemplo, puede estar presente un indicador que indica que el certificado de firma en un nodo determinado es confiable para obtener permisos de firma de Android. Este indicador permite que otras aplicaciones firmadas por el certificado anterior sigan teniendo un permiso de firma definido por una aplicación firmada con el nuevo certificado de firma. Debido a que todo el atributo de prueba de rotación reside en la sección de datos firmados del campo de signer v3, está protegido por la clave utilizada para firmar el apk que contiene.

Este formato impide múltiples claves de firma y la convergencia de diferentes certificados de firma ancestrales a uno (múltiples nodos de inicio a un sumidero común).

Formato

La prueba de rotación se almacena dentro del Bloque APK Signature Scheme v3 con ID 0x3ba06f8c . Su formato es:

  • secuencia con prefijo de longitud de levels prefijo de longitud:
    • signed data prefijo de longitud (por certificado anterior, si existe)
      • certificate X.509 con prefijo de longitud (formulario DER ASN.1)
      • signature algorithm ID (uint32): algoritmo utilizado por cert en el nivel anterior
    • flags (uint32): banderas que indican si este certificado debe estar en la estructura self-confianza-old-certs y para qué operaciones.
    • signature algorithm ID (uint32): debe coincidir con el de la sección de datos firmados en el siguiente nivel.
    • signature con prefijo de longitud sobre los signed data anteriormente

Múltiples certificados

Actualmente, Android trata un APK firmado con varios certificados como una identidad de firma única separada de los certificados que lo componen. Por lo tanto, el atributo de prueba de rotación en la sección de datos firmados forma un gráfico acíclico dirigido, que podría verse mejor como una lista vinculada individualmente, con cada conjunto de firmantes para una versión dada que representa un nodo. Esto agrega complejidad adicional a la estructura de prueba de rotación (versión de múltiples firmantes a continuación). En particular, ordenar se convierte en una preocupación. Además, ya no es posible firmar APK independientemente, porque la estructura de prueba de rotación debe tener los certificados de firma antiguos que firman el nuevo conjunto de certificados, en lugar de firmarlos uno por uno. Por ejemplo, un APK firmado por la tecla A que desea estar firmado por dos nuevas teclas B y C no podría tener el firmante B solo incluye una firma por A o B, porque esa es una identidad de firma diferente a B y C. Esto sería significa que los firmantes deben coordinarse antes de construir tal estructura.

Atributo de prueba de rotación de firmantes múltiples

  • secuencia con prefijo de longitud de sets prefijo de longitud:
    • signed data (por conjunto anterior, si existe)
      • secuencia de certificates longitud prefijada
        • certificate X.509 con prefijo de longitud (formulario DER ASN.1)
      • Secuencia de signature algorithm IDs de signature algorithm IDs (uint32): uno para cada certificado del conjunto anterior, en el mismo orden.
    • flags (uint32): banderas que indican si este conjunto de certs debe estar en la estructura self-Trusted-old-certs y para qué operaciones.
    • secuencia con prefijo de longitud de signatures prefijo de longitud:
      • signature algorithm ID (uint32): debe coincidir con el de la sección de datos firmados
      • signature con prefijo de longitud sobre los signed data anteriormente

Múltiples antepasados ​​en una estructura de prueba de rotación

El esquema v3 tampoco maneja dos claves diferentes que rotan a la misma clave de firma para la misma aplicación. Esto difiere del caso de una adquisición, donde la compañía compradora quisiera mover la aplicación adquirida para usar su clave de firma para compartir permisos. La adquisición se considera un caso de uso compatible porque la nueva aplicación se distinguiría por su nombre de paquete y podría contener su propia estructura de prueba de rotación. El caso no admitido, de la misma aplicación que tiene dos caminos diferentes para llegar al mismo certificado, rompe muchas de las suposiciones hechas en el diseño de rotación de claves.

Verificación

En Android 9 y versiones posteriores, los APK se pueden verificar de acuerdo con el esquema de firma APK v3, v2 o v1. Las plataformas más antiguas ignoran las firmas v3 e intentan verificar las firmas v2, luego v1.

Proceso de verificación de firma de APK

Figura 1. Proceso de verificación de firma de APK

Verificación de APK Signature Scheme v3

  1. Localice el Bloque de firma de APK y verifique que:
    1. Dos campos de tamaño del Bloque de firma de APK contienen el mismo valor.
    2. El Directorio Central ZIP es seguido inmediatamente por el registro ZIP Fin del Directorio Central.
    3. El fin del ZIP del Directorio Central no es seguido por más datos.
  2. Ubique el primer Bloque de firma de APK v3 dentro del Bloque de firma de APK. Si el Bloque v3 está presente, continúe con el paso 3. De lo contrario, vuelva a verificar el APK utilizando el esquema v2 .
  3. Para cada signer en el APK Signature Scheme v3 Block con una versión SDK mínima y máxima que está dentro del alcance de la plataforma actual:
    1. Elija la signature algorithm ID compatible más fuerte de las signatures . El orden de fuerza depende de cada versión de implementación / plataforma.
    2. Verifique la signature correspondiente de las signatures contra los signed data utilizando public key . (Ahora es seguro analizar los signed data ).
    3. Verifique que las versiones mínimas y máximas del SDK en los datos firmados coincidan con las especificadas para el signer .
    4. Verifique que la lista ordenada de ID de algoritmos de firma en digests y signatures sea ​​idéntica. (Esto es para evitar la eliminación / adición de firmas).
    5. Calcule el resumen del contenido de APK utilizando el mismo algoritmo de resumen que el algoritmo de resumen utilizado por el algoritmo de firma.
    6. Verifique que el resumen calculado sea idéntico al digest correspondiente de los digests .
    7. Verifique que SubjectPublicKeyInfo del primer certificate de certificates sea ​​idéntico a public key .
    8. Si el atributo de prueba de rotación existe para el signer verifique que la estructura sea válida y que este signer sea ​​el último certificado de la lista.
  4. La verificación tiene éxito si se encontró exactamente un signer en el rango de la plataforma actual y el paso 3 tuvo éxito para ese signer .

Validación

Para comprobar que su dispositivo admite v3 correctamente, ejecute las pruebas CTS PkgInstallSignatureVerificationTest.java en cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ .