Android 9 prend en charge la rotation des clés APK , ce qui permet aux applications de modifier leur clé de signature dans le cadre d'une mise à jour APK. Pour rendre la rotation pratique, les fichiers 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 APK de v2 à v3 pour permettre l'utilisation des nouvelles et anciennes clés. La V3 ajoute des informations sur les versions de SDK prises en charge et une structure de preuve de rotation au bloc de signature APK.
Bloc de signature APK
Pour maintenir 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 v3 APK Signing Block est le même que v2 . La signature v3 de l'APK est stockée sous la forme d'une paire ID-valeur avec l'ID 0xf05368c0.
Bloc de schéma de signature APK v3
Le schéma v3 est conçu pour être très similaire 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 EC.
Cependant, le schéma v3 ajoute des informations sur les versions SDK prises en charge 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 APK Signature Scheme v3 suit celui de la v2 :
- séquence préfixée par la longueur du
signer
préfixé par la longueur :-
signed data
préfixées par la longueur :- séquence préfixée de longueur de résumés
digests
de longueur :-
signature algorithm ID
(4 octets) -
digest
(avec un préfixe de longueur)
-
- séquence préfixée par la longueur des
certificates
X.509 :-
certificate
X.509 avec préfixe de longueur (formulaire 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 préfixée de longueur d'
additional attributes
préfixés de longueur :-
ID
(uint32) -
value
(longueur variable : longueur de l'attribut supplémentaire - 4 octets) -
ID - 0x3ba06f8c
-
value -
Structure de preuve de rotation
-
- séquence préfixée de longueur de résumés
-
minSDK
(uint32) - doublon de la valeur minSDK dans la section des données signées - utilisé pour ignorer la vérification de cette signature si la plate-forme actuelle n'est pas dans la plage. Doit correspondre à la valeur des données signées. -
maxSDK
(uint32) - duplicata de la valeur maxSDK dans la section des données signées - utilisé pour ignorer la vérification 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 préfixée de longueur de
signatures
préfixées de longueur :-
signature algorithm ID
(uint32) -
signature
précédée d'un préfixe de longueur sursigned data
-
-
public key
avec préfixe de longueur (SubjectPublicKeyInfo, forme ASN.1 DER)
-
Structures de preuve de rotation et d'anciens certificats de confiance
La structure de preuve de rotation permet aux applications de faire pivoter leur certificat de signature sans être bloquées sur les autres applications avec lesquelles elles communiquent. Pour ce faire, les signatures d'application contiennent deux nouveaux éléments de données :
- affirmation pour des 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 auxquels l'application elle-même fait encore confiance
L'attribut de preuve de rotation dans la section des données signées consiste en une liste à liaison unique, chaque nœud contenant un certificat de signature utilisé pour signer les versions précédentes de l'application. Cet attribut est destiné à contenir les structures de données conceptuelles de preuve de rotation et d'anciens certificats de confiance. La liste est triée par version avec le certificat de signature le plus ancien correspondant au nœud racine. La structure de données de preuve de rotation est construite en faisant en sorte que le certificat de chaque nœud signe le suivant dans la liste, et en imprégnant ainsi chaque nouvelle clé avec la preuve qu'elle doit être aussi fiable que la ou les clés plus anciennes.
La structure de données self-trusted-old-certs est construite en ajoutant des indicateurs à chaque nœud indiquant son appartenance et ses propriétés dans l'ensemble. Par exemple, un indicateur peut être présent indiquant que le certificat de signature sur un nœud donné est approuvé pour l'obtention des autorisations de signature Android. Cet indicateur permet aux autres applications signées par l'ancien certificat de continuer à se voir accorder 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 des données signées du champ du signer
v3, il est protégé par la clé utilisée pour signer l'apk contenant.
Ce format empêche plusieurs clés de signature et la convergence de différents certificats de signature d'ancêtre vers un seul (plusieurs nœuds de départ vers un puits commun).
Format
La preuve de rotation est stockée dans le bloc APK Signature Scheme v3 sous l'ID 0x3ba06f8c
. Son format est :
- séquence préfixée de longueur de
levels
préfixés de longueur :-
signed data
préfixées par la longueur (par le certificat précédent - s'il existe)-
certificate
X.509 avec préfixe de longueur (formulaire ASN.1 DER) -
signature algorithm ID
(uint32) - algorithme utilisé par cert au niveau précédent
-
-
flags
(uint32) - drapeaux indiquant si ce certificat doit ou non être dans la structure self-trusted-old-certs, et pour quelles opérations. -
signature algorithm ID
(uint32) - doit correspondre à celui de la section des données signées au niveau suivant. -
signature
précédée d'un préfixe de longueur sur lessigned data
ci-dessus
-
Plusieurs certificats
Android traite actuellement un APK signé avec plusieurs certificats comme ayant une identité de signature unique distincte des certificats qui le composent. Ainsi, l'attribut de preuve de rotation dans la section des données signées forme un graphe acyclique orienté, qui pourrait être mieux considéré comme une liste à liaison simple, chaque ensemble de signataires pour une version donnée représentant un nœud. Cela ajoute une complexité supplémentaire à la structure de preuve de rotation (version multi-signataire ci-dessous). En particulier, la commande devient une préoccupation. De plus, il n'est plus possible de signer des APK indépendamment, car la structure de preuve de rotation doit faire en sorte que les anciens certificats de signature signent le nouvel ensemble de certificats, plutôt que de les signer un par un. Par exemple, un APK signé par la clé A qui souhaite être signé par deux nouvelles clés B et C ne pourrait pas demander au signataire B d'inclure simplement une signature par A ou B, car il s'agit d'une identité de signature différente de B et C. signifie que les signataires doivent se coordonner avant de construire une telle structure.
Attribut de preuve de rotation de plusieurs signataires
- séquence préfixée de longueur d'
sets
préfixés de longueur :-
signed data
(par ensemble précédent - si elles existent)- séquence de
certificates
préfixée par la longueur-
certificate
X.509 avec préfixe de longueur (formulaire ASN.1 DER)
-
- Séquence d'
signature algorithm IDs
(uint32) - un pour chaque certificat de l'ensemble précédent, dans le même ordre.
- séquence de
-
flags
(uint32) - drapeaux indiquant si cet ensemble de certificats doit être ou non dans la structure self-trusted-old-certs, et pour quelles opérations. - séquence préfixée de longueur de
signatures
préfixées de longueur :-
signature algorithm ID
(uint32) - doit correspondre à celui de la section des données signées -
signature
précédée d'un préfixe de longueur sur lessigned data
ci-dessus
-
-
Ancêtres multiples dans la structure de preuve de rotation
Le schéma v3 ne gère pas non plus deux clés différentes tournant vers la même clé de signature pour la même application. Cela diffère du cas d'une acquisition, où la société acquéreuse souhaite déplacer l'application acquise pour utiliser sa clé de signature pour partager les autorisations. L'acquisition est considérée comme un cas d'utilisation pris en charge, car la nouvelle application se distinguerait par son nom de package et pourrait contenir sa propre structure de preuve de rotation. Le cas non pris en charge, de la même application ayant deux chemins différents pour accéder au même certificat, rompt bon nombre des hypothèses formulées dans la conception de la rotation des clés.
Vérification
Dans Android 9 et versions ultérieures, les fichiers APK peuvent être vérifiés selon le schéma de signature APK v3, le schéma v2 ou le schéma v1. Les plates-formes plus anciennes ignorent les signatures v3 et essaient de vérifier les signatures v2, puis v1.
Figure 1. Processus de vérification de signature APK
Vérification du schéma de signature APK v3
- Localisez le bloc de signature APK et vérifiez que :
- Deux champs de taille du bloc de signature APK contiennent la même valeur.
- Le répertoire central ZIP est immédiatement suivi de l'enregistrement de fin de répertoire central ZIP.
- ZIP La fin du répertoire central n'est pas suivie de plus de données.
- Localisez le premier bloc APK Signature Scheme v3 à l'intérieur du bloc de signature APK. Si le bloc v3 est présent, passez à l'étape 3. Sinon, revenez à la vérification de l'APK à l' aide du schéma v2 .
- Pour chaque
signer
du bloc APK Signature Scheme v3 avec une version minimale et maximale du SDK qui se trouve dans la plage de la plate-forme actuelle :- Choisissez l'
signature algorithm ID
pris en charge le plus puissant parmisignatures
. L'ordre de force dépend de chaque version d'implémentation/plate-forme. - Vérifiez la
signature
correspondante à partir dessignatures
par rapport auxsigned data
à l'aidepublic key
. (Il est maintenant sûr d'analysersigned data
.) - Vérifiez que les versions minimale et maximale du SDK dans les données signées correspondent à celles spécifiées pour le
signer
. - Vérifiez que la liste ordonnée des ID d'algorithme de signature dans les
digests
etsignatures
est identique. (Ceci permet d'empêcher la suppression/l'ajout de signature.) - Calculez le résumé du contenu APK en utilisant le même algorithme de résumé que l'algorithme de résumé utilisé par l'algorithme de signature.
- Vérifiez que le résumé calculé est identique au
digest
correspondant dedigests
. - Vérifiez que SubjectPublicKeyInfo du premier
certificate
decertificates
est identique àpublic key
. - Si l'attribut de preuve de rotation existe pour le
signer
, vérifiez que la structure est valide et que cesigner
est le dernier certificat de la liste.
- Choisissez l'
- La vérification réussit si exactement un
signer
a été trouvé dans la plage de la plate-forme actuelle et que l'étape 3 a réussi pour cesigner
.
Validation
Pour tester que votre appareil prend correctement en charge la v3, exécutez les tests PkgInstallSignatureVerificationTest.java
CTS dans cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.