Les images de l'OS Android utilisent des signatures cryptographiques à deux endroits:
- Chaque fichier
.apk
dans l'image doit être signé. Appareils Android Le gestionnaire de packages utilise une signature.apk
de deux manières:- Lorsqu'une application est remplacée, elle doit être signée avec la même clé que la
ancienne application afin d'accéder
aux données de l'ancienne application. Il contient
"true" pour mettre à jour les applications utilisateur en écrasant
.apk
, et pour remplacer une application système par une version plus récente installée sous/data
- Si deux applications ou plus souhaitent partager un ID utilisateur (afin de pouvoir partager données, etc.), ils doivent être signés avec la même clé.
- Lorsqu'une application est remplacée, elle doit être signée avec la même clé que la
ancienne application afin d'accéder
aux données de l'ancienne application. Il contient
"true" pour mettre à jour les applications utilisateur en écrasant
- Les packages de mise à jour OTA doivent être signés avec l'une des clés attendues par ou le processus d'installation les rejettera.
Touches de libération
L'arborescence Android inclut des clés test-keys sous
build/target/product/security
Créer une image de l'OS Android
l'utilisation de make
signera tous les fichiers .apk
à l'aide du
clés de test. Les clés de test étant connues du grand public, n'importe qui peut signer la sienne
Des fichiers .apk avec les mêmes clés, ce qui peut leur permettre de remplacer ou de pirater le système
des applications intégrées à l'image de votre système d'exploitation. C'est pourquoi vous devez impérativement signer
une image de l'OS Android publiée ou déployée publiquement, avec un ensemble spécial
release-keys auxquelles vous seul avez accès.
Pour générer votre propre ensemble unique de clés de publication, exécutez ces commandes depuis racine de votre arborescence Android:
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media networkstack; do \ ./development/tools/make_key ~/.android-certs/$x "$subject"; \ done
$subject
doit être modifié pour refléter les
des informations. Vous pouvez utiliser n'importe quel répertoire, mais veillez à choisir
stocké dans un emplacement
sauvegardé et sécurisé. Certains fournisseurs
choisissent de chiffrer
leur clé privée avec une phrase secrète forte et stocker la clé chiffrée
dans le contrôle des sources. d'autres stockent leurs clés
de libération ailleurs entièrement,
comme sur un ordinateur sous air gap.
Pour générer une image de version, utilisez:
make dist
sign_target_files_apks \ -o \ # explained in the next section --default_key_mappings ~/.android-certs out/dist/*-target_files-*.zip \ signed-target_files.zip
Le script sign_target_files_apks
utilise un élément target-files
.zip
en entrée et génère un nouveau .zip
de fichiers cibles dans
pour lequel tous les fichiers .apk
ont été signés avec de nouvelles clés. Les nouvelles
les images signées se trouvent sous IMAGES/
dans
signed-target_files.zip
Signer les packages OTA
Un fichier ZIP signé de fichiers cibles peut être converti en fichier ZIP de mise à jour OTA signé. en procédant comme suit:
ota_from_target_files \
-k (--package_key)
signed-target_files.zip \
signed-ota_update.zip
Signatures et téléchargement indépendant
Le téléchargement indépendant ne contourne pas la signature normale du package de la récupération. mécanisme de vérification : avant d'installer un package, la récupération vérifie que il est signé avec l'une des clés privées correspondant aux clés publiques stockées dans la partition de récupération, comme elle le ferait pour un paquet livré par voie aérienne.
Les packages de mise à jour reçus du système principal sont généralement validés deux fois:
une fois par le système principal, en utilisant
RecoverySystem.verifyPackage()
dans l'API Android, puis de nouveau
la récupération. L'API RecoverySystem vérifie la signature par rapport aux clés publiques
stocké dans le système principal, dans le fichier /system/etc/security/otacerts.zip
(par défaut). La récupération vérifie la signature par rapport aux clés publiques stockées
sur le disque RAM de la partition de récupération, dans le fichier /res/keys
.
Par défaut, les fichiers cibles .zip
produits par la compilation définissent le
Certificat OTA correspondant à la clé de test. Sur une image libérée, une autre
certificat doit être utilisé afin que les appareils puissent vérifier l'authenticité
"update". En transmettant l'indicateur -o
à
Comme indiqué dans la section précédente, sign_target_files_apks
remplace
le certificat de clé de test avec le certificat de clé de libération de vos certificats
.
Normalement, l'image système et l'image de récupération stockent le même ensemble d'OTA. clés publiques. Le fait d'ajouter une clé uniquement à l'ensemble de clés de récupération permet Possibilité de signer des paquets qui ne peuvent être installés que par téléchargement indépendant (en supposant que le mécanisme de téléchargement des mises à jour du système principal fonctionne correctement vérification par rapport à otacerts.zip). Vous pouvez spécifier des clés supplémentaires inclus uniquement dans la récupération en définissant dans la définition de votre produit:
vendor/yoyodyne/tardis/products/tardis.mk
[...] PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload
Cela inclut la clé publique
vendor/yoyodyne/security/tardis/sideload.x509.pem
en récupération
de clés afin d'installer des packages signés
avec lui. Cette clé supplémentaire n'est pas incluse dans otacerts.zip.
les systèmes qui vérifient correctement les packages téléchargés n’invoquent pas la récupération pour
packages signés avec cette clé.
Certificats et clés privées
Chaque clé est fournie dans deux fichiers: le certificat, qui contient le l'extension .x509.pem, et la clé privée, qui porte l'extension .pk8. La clé privée doit être gardée secrète et est nécessaire pour signer un package. La clé peut elle-même être protégée par un mot de passe. Le certificat, dans En revanche, il ne contient que la moitié publique de la clé, qui peut donc être distribué largement. Il permet de vérifier qu'un package a été signé par la personne clé privée.
Le build Android standard utilise cinq clés, qui se trouvent toutes dans
build/target/product/security
:
- clé d'essai
- Clé par défaut générique pour les packages qui ne spécifient pas de clé.
- plateforme
- Clé de test pour les packages faisant partie de la plate-forme principale.
- partagé
- Clé de test pour les éléments partagés dans le processus de la maison/des contacts.
- Multimédia
- Clé de test pour les packages intégrés au système de téléchargement/de médias.
Les packages individuels spécifient l'une de ces clés en définissant LOCAL_CERTIFICATE dans son fichier Android.mk. (testkey est utilisé si cette variable n'est pas définie). Toi peut également spécifier une clé entièrement différente par nom de chemin, par exemple :
device/yoyodyne/apps/SpecialApp/Android.mk
[...] LOCAL_CERTIFICATE := device/yoyodyne/security/special
La compilation utilise maintenant la clé device/yoyodyne/security/special.{x509.pem,pk8}
pour signer SpecialApp.apk. La compilation ne peut utiliser que des clés privées
ne sont pas protégés par un mot de passe.
Options de signature avancées
Remplacement de la clé de signature d'APK
Le script de signature sign_target_files_apks
fonctionne sur la cible.
des fichiers générés pour une compilation. Toutes les informations sur les certificats
utilisées au moment de la compilation sont incluses dans les fichiers cibles. Lors de l'exécution de la
script de signature pour signer la publication, les clés de signature peuvent être remplacées en fonction
ou le nom de l'APK.
Utiliser --key_mapping
et --default_key_mappings
pour spécifier le remplacement de clé en fonction des noms de clés:
- L'option
--key_mapping src_key=dest_key
spécifie le remplacement d'une clé à la fois. - L'option
--default_key_mappings dir
spécifie avec cinq clés pour remplacer toutes les clés debuild/target/product/security
; cela revient à utiliser--key_mapping
cinq fois pour spécifier les mappages.
build/target/product/security/testkey = dir/releasekey build/target/product/security/platform = dir/platform build/target/product/security/shared = dir/shared build/target/product/security/media = dir/media build/target/product/security/networkstack = dir/networkstack
Utilisez les
--extra_apks apk_name1,apk_name2,...=key
indicateur
pour spécifier les remplacements de clés de signature en fonction des noms d'APK. Si
key
est vide, le script traite les APK spécifiés
présignée.
Pour le produit tardis fictif, vous avez besoin de six clés protégées par mot de passe:
cinq pour remplacer les cinq dans build/target/product/security
, et un
pour remplacer la clé supplémentaire device/yoyodyne/security/special
requises par SpecialApp
dans l'exemple ci-dessus. Si les clés se trouvent dans
:
vendor/yoyodyne/security/tardis/releasekey.x509.pem vendor/yoyodyne/security/tardis/releasekey.pk8 vendor/yoyodyne/security/tardis/platform.x509.pem vendor/yoyodyne/security/tardis/platform.pk8 vendor/yoyodyne/security/tardis/shared.x509.pem vendor/yoyodyne/security/tardis/shared.pk8 vendor/yoyodyne/security/tardis/media.x509.pem vendor/yoyodyne/security/tardis/media.pk8 vendor/yoyodyne/security/tardis/networkstack.x509.pem vendor/yoyodyne/security/tardis/networkstack.pk8 vendor/yoyodyne/security/special.x509.pem vendor/yoyodyne/security/special.pk8 # NOT password protected vendor/yoyodyne/security/special-release.x509.pem vendor/yoyodyne/security/special-release.pk8 # password protected
Ensuite, vous signeriez toutes les applications comme ceci:
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--key_mapping vendor/yoyodyne/security/special=vendor/yoyodyne/security/special-release \
--extra_apks PresignedApp= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
Cela a pour effet d'afficher ce qui suit:
Enter password for vendor/yoyodyne/security/special-release key> Enter password for vendor/yoyodyne/security/tardis/networkstack key> Enter password for vendor/yoyodyne/security/tardis/media key> Enter password for vendor/yoyodyne/security/tardis/platform key> Enter password for vendor/yoyodyne/security/tardis/releasekey key> Enter password for vendor/yoyodyne/security/tardis/shared key> signing: Phone.apk (vendor/yoyodyne/security/tardis/platform) signing: Camera.apk (vendor/yoyodyne/security/tardis/media) signing: NetworkStack.apk (vendor/yoyodyne/security/tardis/networkstack) signing: Special.apk (vendor/yoyodyne/security/special-release) signing: Email.apk (vendor/yoyodyne/security/tardis/releasekey) [...] signing: ContactsProvider.apk (vendor/yoyodyne/security/tardis/shared) signing: Launcher.apk (vendor/yoyodyne/security/tardis/shared) NOT signing: PresignedApp.apk (skipped due to special cert string) rewriting SYSTEM/build.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys signing: framework-res.apk (vendor/yoyodyne/security/tardis/platform) rewriting RECOVERY/RAMDISK/default.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys using: vendor/yoyodyne/security/tardis/releasekey.x509.pem for OTA package verification done.
Une fois que l'utilisateur a été invité à saisir le mot de passe de toutes les clés protégées par un mot de passe,
le script signe de nouveau tous les fichiers APK dans la cible d'entrée .zip
avec le
clés de libération. Avant d'exécuter la commande, vous pouvez également définir
ANDROID_PW_FILE
vers un nom de fichier temporaire. la
appelle ensuite votre éditeur pour vous permettre de saisir des mots de passe pour toutes les clés
(il peut s'agir d'un moyen plus pratique de saisir des mots de passe).
Remplacement de la clé de signature APEX
Android 10 introduit Format de fichier ApEX pour l'installation des modules système de niveau inférieur. Comme expliqué dans Signature ApEX, chaque fichier APEX est signé avec deux clés: une pour l'image du mini-système de fichiers dans un élément APEX et l'autre pour pour l'ensemble de l'apex.
Lors de la signature pour la publication, les deux clés de signature d'un fichier APEX sont remplacées
avec des clés de déverrouillage. La clé de charge utile du système de fichiers est spécifiée avec le
l'option --extra_apex_payload
et l'intégralité de la clé de signature du fichier APEX est
spécifiée avec l'option --extra_apks
.
Pour le produit tardis, supposons que vous disposez de la configuration de clé suivante :
pour com.android.conscrypt.apex
,
com.android.media.apex
com.android.runtime.release.apex
fichiers APEX.
name="com.android.conscrypt.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.media.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.runtime.release.apex" public_key="vendor/yoyodyne/security/testkeys/com.android.runtime.avbpubkey" private_key="vendor/yoyodyne/security/testkeys/com.android.runtime.pem" container_certificate="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.x509.pem" container_private_key="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.pk8"
Les fichiers suivants contiennent les clés de libération:
vendor/yoyodyne/security/runtime_apex_container.x509.pem vendor/yoyodyne/security/runtime_apex_container.pk8 vendor/yoyodyne/security/runtime_apex_payload.pem
La commande suivante remplace les clés de signature pour
com.android.runtime.release.apex
et
com.android.tzdata.apex
lors de la signature de la version. En particulier,
com.android.runtime.release.apex
est signé avec le
clés de libération (runtime_apex_container
pour le fichier APEX et
runtime_apex_payload
pour la charge utile de l'image de fichier).
com.android.tzdata.apex
est traité comme présigné. Tous les autres apex
sont gérés par la configuration par défaut
comme indiqué dans les fichiers cibles.
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--extra_apks com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_container \
--extra_apex_payload_key com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_payload.pem \
--extra_apks com.android.media.apex= \
--extra_apex_payload_key com.android.media.apex= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
L'exécution de la commande ci-dessus génère les journaux suivants:
[...] signing: com.android.runtime.release.apex container (vendor/yoyodyne/security/runtime_apex_container) : com.android.runtime.release.apex payload (vendor/yoyodyne/security/runtime_apex_payload.pem) NOT signing: com.android.conscrypt.apex (skipped due to special cert string) NOT signing: com.android.media.apex (skipped due to special cert string) [...]
Autres options
Le script de signature sign_target_files_apks
réécrit la compilation.
une description et une empreinte numérique dans les fichiers de propriétés de compilation pour indiquer que
est une compilation signée. L'indicateur --tag_changes
contrôle les modifications
à l'empreinte digitale. Exécutez le script avec -h
pour voir
sur tous les indicateurs.
Générer des clés manuellement
Android utilise des clés RSA 2 048 bits avec exposant public 3. Vous pouvez générer de clé privée/certificat à l'aide de l'outil OpenSSL openssl.org:
# generate RSA keyopenssl genrsa -3 -out temp.pem 2048
Generating RSA private key, 2048 bit long modulus ....+++ .....................+++ e is 3 (0x3) # create a certificate with the public part of the keyopenssl req -new -x509 -key temp.pem -out releasekey.x509.pem -days 10000 -subj '/C=US/ST=California/L=San Narciso/O=Yoyodyne, Inc./OU=Yoyodyne Mobility/CN=Yoyodyne/emailAddress=yoyodyne@example.com'
# create a PKCS#8-formatted version of the private keyopenssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt
# securely delete the temp.pem fileshred --remove temp.pem
La commande opensl pkcs8 donnée ci-dessus crée un fichier .pk8 avec no
mot de passe, adapté à une utilisation avec le système de compilation. Pour créer un fichier .pk8 sécurisé
par un mot de passe (ce que vous devez faire pour toutes les clés de libération), remplacez
Argument -nocrypt
avec -passout stdin
; puis OpenSSL
chiffrera la clé privée avec un mot
de passe lu à partir de l’entrée standard. Non
est affichée, donc si stdin est le terminal, le programme semble se figer.
quand il n’y a qu’à attendre que
vous saisissiez un mot de passe. D'autres valeurs peuvent être
utilisé pour l'argument-passout afin de lire le mot de passe à partir d'autres emplacements ; pour
consultez les
<ph type="x-smartling-placeholder"></ph>
la documentation OpenSSL.
Le fichier intermédiaire temp.pem contient la clé privée protection par mot de passe. Vous devez donc l'utiliser de manière réfléchie lors de la génération clés. En particulier, l'utilitaire GNUshred peut ne pas être efficace sur le réseau ou systèmes de fichiers journalisés. Vous pouvez utiliser un répertoire de travail situé sur un disque RAM (comme une partition tmpfs) lors de la génération de clés pour garantir que ne sont pas exposées par inadvertance.
Créer des fichiers image
Lorsque vous disposez de signed-target_files.zip
, vous devez
créer l'image pour pouvoir
la mettre sur un appareil.
Pour créer l'image signée à partir des fichiers cibles, exécutez la commande suivante :
la commande suivante à partir de la racine
arborescence:
img_from_target_files signed-target_files.zip signed-img.zip
signed-img.zip
, contient tous les fichiers .img
.
Pour charger une image sur un appareil, utilisez fastboot en tant que
ce qui suit:
fastboot update signed-img.zip