APK Signature Scheme v3

Android 9 est compatible avec la rotation des clés APK, ce qui permet aux applications de modifier leur clé de signature lors d'une mise à jour de l'APK. Pour que la rotation soit pratique, les APK doivent indiquer les niveaux de confiance entre la nouvelle et l'ancienne clé de signature. Pour prendre en charge la rotation des clés, nous avons mis à jour le schéma de signature des APK de la version 2 à la version 3 afin de permettre l'utilisation des nouvelles et anciennes clés. La version 3 ajoute des informations sur les versions de SDK compatibles et une struct de preuve de rotation au bloc de signature de l'APK.

Bloc de signature de l'APK

Pour assurer la rétrocompatibilité avec le format APK v1, les signatures APK v2 et v3 sont stockées dans un bloc de signature APK, situé immédiatement avant le répertoire central ZIP.

Le format de bloc de signature de l'APK v3 est le même que celui de la version v2. La signature v3 de l'APK est stockée sous la forme d'une paire ID-valeur avec l'ID 0xf05368c0.

Bloc du schéma de signature APK v3

Le schéma v3 est conçu pour être très semblable au schéma v2. Il a le même format général et prend en charge les mêmes ID d'algorithme de signature, tailles de clé et courbes elliptiques.

Toutefois, le schéma v3 ajoute des informations sur les versions de SDK compatibles et la structure de preuve de rotation.

Format

Le bloc APK Signature Scheme v3 est stocké dans le bloc de signature APK sous l'ID 0xf05368c0.

Le format du bloc du schéma de signature des fichiers APK v3 suit celui de la version v2:

  • Séquence avec préfixe de longueur de signer avec préfixe de longueur :
    • signed data avec préfixe de longueur :
      • Séquence avec préfixe de longueur de digests avec préfixe de longueur :
        • signature algorithm ID (4 octets)
        • digest (préfixe de longueur)
      • Séquence avec préfixe de longueur de certificates X.509 :
        • certificate X.509 avec préfixe de longueur (format ASN.1 DER)
      • minSDK (uint32) : ce signataire doit être ignoré si la version de la plate-forme est inférieure à ce nombre.
      • maxSDK (uint32) : ce signataire doit être ignoré si la version de la plate-forme est supérieure à ce nombre.
      • Séquence avec préfixe de longueur de additional attributes avec préfixe de longueur :
        • ID (uint32)
        • value (longueur variable: longueur de l'attribut supplémentaire - 4 octets)
        • ID - 0x3ba06f8c
        • value - Structure de preuve de rotation
    • minSDK (uint32) : duplique de la valeur minSDK dans la section de données signées. Permet d'ignorer la validation de cette signature si la plate-forme actuelle n'est pas comprise dans la plage. Doit correspondre à la valeur des données signées.
    • maxSDK (uint32) : duplique de la valeur maxSDK dans la section de données signées. Permet d'ignorer la validation de cette signature si la plate-forme actuelle n'est pas dans la plage. Doit correspondre à la valeur des données signées.
    • Séquence avec préfixe de longueur de signatures avec préfixe de longueur :
      • signature algorithm ID (uint32)
      • signature avec préfixe de longueur sur signed data
    • public key avec préfixe de longueur (SubjectPublicKeyInfo, format ASN.1 DER)

Structures proof-of-rotation et self-trusted-old-certs

La structure de preuve de rotation permet aux applications de faire pivoter leur certificat de signature sans être bloquées sur d'autres applications avec lesquelles elles communiquent. Pour ce faire, les signatures d'application contiennent deux nouvelles données:

  • affirmation pour les tiers que le certificat de signature de l'application peut être approuvé partout où ses prédécesseurs sont approuvés
  • les anciens certificats de signature de l'application que l'application elle-même continue de valider ;

L'attribut proof-of-rotation de la section "signed-data" se compose d'une liste à une seule liaison, chaque nœud contenant un certificat de signature utilisé pour signer les versions précédentes de l'application. Cet attribut est censé contenir les structures de données conceptuelles proof-of-rotation et self-trusted-old-certs. La liste est triée par version, le certificat de signature le plus ancien correspondant au nœud racine. La structure de données de preuve de rotation est créée en demandant au certificat de chaque nœud de signer le suivant de la liste, et en infusant ainsi à chaque nouvelle clé la preuve qu'elle doit être aussi fiable que l'ancienne ou les anciennes clés.

La structure de données self-trusted-old-certs est construite en ajoutant des indicateurs à chaque nœud pour indiquer son appartenance et ses propriétés dans l'ensemble. Par exemple, un indicateur peut être présent pour indiquer que le certificat de signature d'un nœud donné est approuvé pour obtenir des autorisations de signature Android. Cet indicateur permet aux autres applications signées par l'ancien certificat de bénéficier toujours d'une autorisation de signature définie par une application signée avec le nouveau certificat de signature. Étant donné que l'ensemble de l'attribut de preuve de rotation réside dans la section de données signées du champ signer v3, il est protégé par la clé utilisée pour signer l'APK contenant.

Ce format exclut les multiples clés de signature et la convergence de différents certificats de signature d'ancêtres vers un seul (plusieurs nœuds de départ vers un même point de terminaison).

Format

La preuve de rotation est stockée dans le bloc du schéma de signature APK v3 sous l'ID 0x3ba06f8c. Son format est le suivant:

  • Séquence avec préfixe de longueur de levels avec préfixe de longueur :
    • signed data avec préfixe de longueur (par le certificat précédent, le cas échéant)
      • certificate X.509 avec préfixe de longueur (format ASN.1 DER)
      • signature algorithm ID (uint32) : algorithme utilisé par le certificat au niveau précédent
    • flags (uint32) : indicateurs indiquant si ce certificat doit figurer dans la structure self-trusted-old-certs et pour quelles opérations.
    • signature algorithm ID (uint32) : doit correspondre à celui de la section de données signées au niveau suivant.
    • signature avec préfixe de longueur au-dessus de signed data ci-dessus

Plusieurs certificats

Plusieurs signataires ne sont pas acceptés, et Google Play ne publie pas d'applications signées avec plusieurs certificats.

Validation

Sous Android 9 et versions ultérieures, les APK peuvent être validés selon le schéma de signature APK v3, v2 ou v1. Les plates-formes plus anciennes ignorent les signatures v3 et tentent de valider les signatures v2, puis les signatures v1.

Processus de validation de la signature d'un APK

Figure 1 : Processus de validation de la signature de l'APK

Vérification du schéma de signature des fichiers APK v3

  1. Recherchez le bloc de signature de l'APK et vérifiez les points suivants :
    1. Deux champs de taille du bloc de signature de l'APK contiennent la même valeur.
    2. L'enregistrement ZIP End of Central Directory est immédiatement suivi par l'enregistrement ZIP Central Directory.
    3. La fin du répertoire central ZIP n'est pas suivie d'autres données.
  2. Recherchez le premier bloc APK Signature Scheme v3 dans le bloc de signature de l'APK. Si le bloc v3 est présent, passez à l'étape 3. Sinon, vérifiez l'APK à l'aide du schéma v2.
  3. Pour chaque signer du bloc APK Signature Scheme v3 avec une version de SDK minimale et maximale comprise dans la plage de la plate-forme actuelle :
    1. Choisissez le signature algorithm ID le plus puissant compatible dans signatures. L'ordre de force dépend de chaque implémentation/version de plate-forme.
    2. Vérifiez le signature correspondant de signatures avec signed data à l'aide de public key. (Vous pouvez désormais analyser signed data en toute sécurité.)
    3. Vérifiez que les versions minimales et maximales du SDK dans les données signées correspondent à celles spécifiées pour signer.
    4. Vérifiez que la liste ordonnée des ID d'algorithme de signature dans digests et signatures est identique. (Cela permet d'éviter le retrait/l'ajout de signature.)
    5. Calculez le condensé du contenu de l'APK à l'aide du même algorithme de condensé que celui utilisé par l'algorithme de signature.
    6. Vérifiez que le récapitulatif calculé est identique à l'digest correspondant de digests.
    7. Vérifiez que SubjectPublicKeyInfo du premier certificate de certificates est identique à public key.
    8. Si l'attribut de preuve de rotation existe pour signer, vérifiez que la struct est valide et que signer est le dernier certificat de la liste.
  4. La validation aboutit si exactement un signer a été trouvé dans la plage de la plate-forme actuelle et si l'étape 3 a réussi pour ce signer.

Validation

Pour vérifier que votre appareil est compatible avec la version 3, exécutez les tests CTS PkgInstallSignatureVerificationTest.java dans cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.