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 v2

APK Signature Scheme v2 es un esquema de firma de archivo completo que aumenta la velocidad de verificación y fortalece las garantías de integridad al detectar cualquier cambio en las partes protegidas del APK.

La firma con el APK Signature Scheme v2 inserta un bloque de firma de APK en el archivo APK inmediatamente antes de la sección ZIP Central Directory. Dentro del Bloque de firma APK, las firmas v2 y la información de identidad del firmante se almacenan en un Bloque v2 del Esquema de firma APK .

APK antes y después de firmar

Figura 1. APK antes y después de firmar

APK Signature Scheme v2 se introdujo en Android 7.0 (Nougat). Para hacer que un APK sea instalable en Android 6.0 (Marshmallow) y dispositivos más antiguos, el APK debe firmarse utilizando la firma JAR antes de firmar con el esquema v2.

Bloque de firma de APK

Para mantener la compatibilidad con el formato APK v1, v2 y las firmas APK más recientes se almacenan dentro de un Bloque de firma APK, un nuevo contenedor introducido para admitir el APK Signature Scheme v2. En un archivo APK, el Bloque de Firma APK se encuentra inmediatamente antes del Directorio Central ZIP, que se encuentra al final del archivo.

El bloque contiene pares de valores de ID envueltos de una manera que hace que sea más fácil localizar el bloque en el APK. La firma v2 del APK se almacena como un par ID-valor con ID 0x7109871a.

Formato

El formato del bloque de firma de APK es el siguiente (todos los campos numéricos son little-endian):

  • size of block en bytes (excluyendo este campo) (uint64)
  • Secuencia de pares de valores de identificación con el prefijo uint64-length:
    • ID (uint32)
    • value (longitud variable: longitud del par - 4 bytes)
  • size of block en bytes, igual que el primer campo (uint64)
  • magic "APK Sig Block 42" (16 bytes)

APK se analiza al encontrar primero el inicio del directorio central de ZIP (al encontrar el registro de fin de ZIP del directorio central al final del archivo y luego leer el desplazamiento inicial del directorio central del registro). El valor magic proporciona una forma rápida de establecer que lo que precede al Directorio Central es probablemente el Bloque de firma de APK. El size of block valor size of block apunta eficientemente al inicio del bloque en el archivo.

Los pares de valores de ID con ID desconocidos deben ignorarse al interpretar el bloque.

Bloque de esquema de firma v2 APK

APK está firmado por uno o más firmantes / identidades, cada uno representado por una clave de firma. Esta información se almacena como un APK Signature Scheme v2 Block. Para cada firmante, se almacena la siguiente información:

  • (algoritmo de firma, resumen, firma) tuplas. El resumen se almacena para desacoplar la verificación de firma de la comprobación de integridad de los contenidos del APK.
  • Cadena de certificado X.509 que representa la identidad del firmante.
  • Atributos adicionales como pares clave-valor.

Para cada firmante, el APK se verifica utilizando una firma compatible de la lista provista. Las firmas con algoritmos de firma desconocidos se ignoran. Depende de cada implementación elegir qué firma usar cuando se encuentran varias firmas compatibles. Esto permite la introducción de métodos de firma más fuertes en el futuro de una manera compatible con versiones anteriores. El enfoque sugerido es verificar la firma más fuerte.

Formato

APK Signature Scheme v2 Block se almacena dentro del APK Signing Block bajo ID 0x7109871a .

El formato del Bloque v2 del Esquema de firma APK es el siguiente (todos los valores numéricos son little endian, todos los campos con prefijo de longitud usan uint32 para la longitud):

  • secuencia con prefijo de longitud del signer prefijo de longitud:
    • signed data prefijo de longitud:
      • secuencia de longitud prefijada de longitud prefijada digests :
      • secuencia de prefijos de longitud de certificates X.509:
        • certificate X.509 con prefijo de longitud (formulario DER ASN.1)
      • secuencia con prefijo de longitud de additional attributes prefijo de longitud:
        • ID (uint32)
        • value (longitud variable: longitud del atributo adicional - 4 bytes)
    • 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)

ID de algoritmo de firma

  • 0x0101: RSASSA-PSS con resumen SHA2-256, SHA2-256 MGF1, 32 bytes de sal, avance: 0xbc
  • 0x0102: RSASSA-PSS con resumen SHA2-512, SHA2-512 MGF1, 64 bytes de sal, avance: 0xbc
  • 0x0103: RSASSA-PKCS1-v1_5 con resumen SHA2-256. Esto es para sistemas de compilación que requieren firmas deterministas.
  • 0x0104: RSASSA-PKCS1-v1_5 con resumen SHA2-512. Esto es para sistemas de compilación que requieren firmas deterministas.
  • 0x0201 — ECDSA con digestión SHA2-256
  • 0x0202 — ECDSA con digestión SHA2-512
  • 0x0301: DSA con resumen SHA2-256

Todos los algoritmos de firma anteriores son compatibles con la plataforma Android. Las herramientas de firma pueden admitir un subconjunto de algoritmos.

Tamaños de teclas admitidas y curvas CE:

  • RSA: 1024, 2048, 4096, 8192, 16384
  • CE: NIST P-256, P-384, P-521
  • DSA: 1024, 2048, 3072

Contenidos protegidos por integridad

Para proteger el contenido del APK, un APK consta de cuatro secciones:

  1. Contenido de las entradas ZIP (desde el desplazamiento 0 hasta el inicio del Bloque de firma de APK)
  2. Bloque de firma de APK
  3. Directorio Central ZIP
  4. ZIP Fin del Directorio Central

Secciones de APK después de firmar

Figura 2. Secciones de APK después de firmar

APK Signature Scheme v2 protege la integridad de las secciones 1, 3, 4 y los bloques de signed data del APK Signature Scheme v2 Block contenidos dentro de la sección 2.

La integridad de las secciones 1, 3 y 4 está protegida por uno o más resúmenes de sus contenidos almacenados en bloques de signed data que, a su vez, están protegidos por una o más firmas.

El resumen sobre las secciones 1, 3 y 4 se calcula de la siguiente manera, similar a un árbol Merkle de dos niveles. Cada sección se divide en fragmentos consecutivos de 1 MB (2 20 bytes). El último fragmento en cada sección puede ser más corto. El resumen de cada fragmento se calcula sobre la concatenación del byte 0xa5 , la longitud del fragmento en bytes (little-endian uint32) y el contenido del fragmento. El resumen de nivel superior se calcula sobre la concatenación del byte 0x5a , el número de fragmentos (little-endian uint32) y la concatenación de resúmenes de los fragmentos en el orden en que aparecen los fragmentos en el APK. El resumen se calcula de manera fragmentada para permitir acelerar el cálculo paralelizándolo.

Resumen de APK

Figura 3. Resumen de APK

La protección de la sección 4 (ZIP End of Central Directory) se complica por la sección que contiene el desplazamiento del ZIP Central Directory. El desplazamiento cambia cuando cambia el tamaño del Bloque de firma de APK, por ejemplo, cuando se agrega una nueva firma. Por lo tanto, cuando se computa el resumen sobre el extremo ZIP del directorio central, el campo que contiene el desplazamiento del directorio central ZIP debe tratarse como si contuviera el desplazamiento del bloque de firma APK.

Protecciones de retroceso

Un atacante podría intentar que se verifique un APK firmado con v2 como un APK firmado con v1 en plataformas Android que admitan la verificación de un APK firmado con v2. Para mitigar este ataque, los APK firmados con v2 que también están firmados con v1 deben contener un atributo X-Android-APK-Signed en la sección principal de sus archivos META-INF / *. SF. El valor del atributo es un conjunto de ID de esquema de firma APK separados por comas (la ID de este esquema es 2). Al verificar la firma v1, se requiere el verificador APK para rechazar los APK que no tienen una firma para el esquema de firma APK que el verificador prefiere de este conjunto (por ejemplo, esquema v2). Esta protección se basa en el hecho de que los archivos META-INF / *. SF de contenido están protegidos por firmas v1. Consulte la sección sobre la verificación de APK firmada por JAR .

Un atacante podría intentar quitar firmas más fuertes del Bloque v2 de APK Signature Scheme. Para mitigar este ataque, la lista de ID de algoritmos de firma con la que se firmó el APK se almacena en el bloque de signed data que está protegido por cada firma.

Verificación

En Android 7.0 y versiones posteriores, los APK se pueden verificar de acuerdo con el esquema de firma APK v2 + o la firma JAR (esquema v1). Las plataformas más antiguas ignoran las firmas v2 y solo verifican las firmas v1.

Proceso de verificación de firma de APK

Figura 4. Proceso de verificación de firma de APK (nuevos pasos en rojo)

Verificación de APK Signature Scheme v2

  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 APK Signature Scheme v2 dentro del bloque de firma de APK. Si el Bloque v2 está presente, continúe con el paso 3. De lo contrario, vuelva a verificar el APK utilizando el esquema v1 .
  3. Para cada signer en el APK Signature Scheme v2 Block:
    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 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).
    4. Calcule el resumen de contenido de APK utilizando el mismo algoritmo de resumen que el algoritmo de resumen utilizado por el algoritmo de firma.
    5. Verifique que el resumen calculado sea idéntico al digest correspondiente de los digests .
    6. Verifique que SubjectPublicKeyInfo del primer certificate de certificates sea ​​idéntico a public key .
  4. La verificación tiene éxito si se encontró al menos un signer y el paso 3 tuvo éxito para cada signer encontrado.

Nota : APK no debe verificarse usando el esquema v1 si ocurre una falla en los pasos 3 o 4.

Verificación de APK firmada por JAR (esquema v1)

El APK firmado con JAR es un JAR firmado estándar , que debe contener exactamente las entradas enumeradas en META-INF / MANIFEST.MF y donde todas las entradas deben estar firmadas por el mismo conjunto de firmantes. Su integridad se verifica de la siguiente manera:

  1. Cada firmante está representado por una entrada JAR META-INF / <signer> .SF y META-INF / <signer>. (RSA | DSA | EC).
  2. <signer>. (RSA | DSA | EC) es un PKCS # 7 CMS ContentInfo con estructura SignedData cuya firma se verifica sobre el archivo <signer> .SF.
  3. El archivo <signer> .SF contiene un resumen de archivo completo de META-INF / MANIFEST.MF y resúmenes de cada sección de META-INF / MANIFEST.MF. Se verifica el resumen del archivo completo de MANIFEST.MF. Si eso falla, el resumen de cada sección MANIFEST.MF se verifica en su lugar.
  4. META-INF / MANIFEST.MF contiene, para cada entrada JAR protegida con integridad, una sección correspondiente que contiene el resumen del contenido sin comprimir de la entrada. Todos estos resúmenes se verifican.
  5. La verificación del APK falla si el APK contiene entradas JAR que no figuran en MANIFEST.MF y no son parte de la firma JAR.

La cadena de protección es, por lo tanto, <signer>. (RSA | DSA | EC) -> <signer> .SF -> MANIFEST.MF -> contenido de cada entrada JAR protegida por integridad.