Builds für die Veröffentlichung signieren

Android OS-Images verwenden an zwei Stellen kryptografische Signaturen:

  1. Jede .apk - Datei innerhalb des Bildes muss unterzeichnet werden. Android Package Manager verwendet eine .apk - Unterschrift auf zwei Arten:
    • Wenn eine Anwendung ersetzt wird, muss sie mit dem gleichen Schlüssel wie die alte Anwendung signiert werden, um Zugriff auf die Daten der alten Anwendung zu erhalten. Dies gilt sowohl für die vom User Apps Aktualisierung des Überschreiben .apk , und einen System - App mit einer neueren Version für das Überschreiben unter installiert /data .
    • Wenn zwei oder mehr Anwendungen eine Benutzer-ID teilen möchten (um Daten auszutauschen usw.), müssen sie mit demselben Schlüssel signiert werden.
  2. OTA-Update-Pakete müssen mit einem der vom System erwarteten Schlüssel signiert werden, sonst werden sie vom Installationsprozess abgelehnt.

Tasten loslassen

Der Android - Baum enthält Test-Tasten unter build/target/product/security . Der Aufbau eines Android OS Bild mit make alle unterzeichnen .apk - Dateien mit den Test-Tasten. Da die Testschlüssel öffentlich bekannt sind, kann jeder seine eigenen .apk-Dateien mit den gleichen Schlüsseln signieren, was es ihm ermöglicht, in Ihr Betriebssystem-Image integrierte System-Apps zu ersetzen oder zu entführen. Aus diesem Grunde ist es wichtig , alle bereits veröffentlichtes oder bereitgestellt Android OS - Bild mit einem speziellen Satz von Release-Tasten zu unterschreiben , dass Sie nur Zugriff haben.

Um Ihren eigenen einzigartigen Satz von Freigabeschlüsseln zu generieren, führen Sie diese Befehle im Stammverzeichnis Ihres Android-Baums aus:

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 sollte geändert werden Ihre Organisation Informationen zu reflektieren. Sie können jedes beliebige Verzeichnis verwenden, aber achten Sie darauf, einen gesicherten und sicheren Speicherort auszuwählen. Einige Anbieter verschlüsseln ihren privaten Schlüssel mit einer starken Passphrase und speichern den verschlüsselten Schlüssel in der Quellcodeverwaltung. andere speichern ihre Freigabeschlüssel ganz woanders, beispielsweise auf einem Computer mit Luftspalt.

Um ein Release-Image zu generieren, verwenden Sie:

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

Das sign_target_files_apks Skript nimmt eine ziel Dateien .zip als Eingabe und erzeugt eine neue Ziel-Dateien .zip , in dem alle die .apk - Dateien mit neuen Schlüsseln signiert wurden. Die neu signierte Bilder finden Sie unter IMAGES/ in signed-target_files.zip .

OTA-Pakete signieren

Ein unterzeichneter Ziel-Dateien zip kann in einem signierten OTA - Update zip umgewandelt, mit dem folgenden Verfahren:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

Signaturen und Sideloading

Sideloading umgeht nicht den normalen Überprüfungsmechanismus der Paketsignatur – vor der Installation eines Pakets überprüft Recovery, dass es mit einem der privaten Schlüssel signiert ist, der den in der Wiederherstellungspartition gespeicherten öffentlichen Schlüsseln entspricht, genau wie bei einem Paket, das über die -Luft.

Update - Pakete von dem Hauptsystem empfangen werden typischerweise zweimal überprüft: einmal von dem Hauptsystem, unter Verwendung der RecoverySystem.verifyPackage() Methode in der Android API, und dann wieder durch Rückgewinnung. Die RecoverySystem API überprüft die Signatur mit öffentlichen Schlüsseln im Hauptsystem gespeichert ist , in der Datei /system/etc/security/otacerts.zip (Standardeinstellung). Recovery überprüft die Signatur mit öffentlichen Schlüsseln in der Wiederherstellungspartition RAM - Disk gespeichert sind , in der Datei /res/keys .

Standardmäßig werden die Ziel-Dateien .zip durch den Build setzt die OTA - Zertifikat erzeugt die Testtaste übereinstimmen. Auf einem freigegebenen Image muss ein anderes Zertifikat verwendet werden, damit Geräte die Authentizität des Aktualisierungspakets überprüfen können. Vorbei an den -o - Flag auf sign_target_files_apks , wie im vorherigen Abschnitt gezeigt, ersetzt den Tests - Key - Zertifikat mit dem Release - Key - Zertifikat von Ihrem certs - Verzeichnis.

Normalerweise speichern das System-Image und das Wiederherstellungs-Image denselben Satz öffentlicher OTA-Schlüssel. Durch das Hinzufügen einer Taste nur auf die Wiederherstellung Satz Schlüssel ist es möglich , Pakete zu unterzeichnen , die nur über sideloading installiert werden kann (das Hauptsystem des Update - Download - Mechanismus unter der Annahme Überprüfung gegen otacerts.zip richtig tun). Sie können zusätzliche Schlüssel angeben, die nur in die Wiederherstellung eingeschlossen werden sollen, indem Sie die Variable PRODUCT_EXTRA_RECOVERY_KEYS in Ihrer Produktdefinition festlegen:

vendor/yoyodyne/tardis/products/tardis.mk
 [...]

PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload

Dazu gehört auch die Public - Key - vendor/yoyodyne/security/tardis/sideload.x509.pem in der Wiederherstellungsschlüssel - Datei , so dass es Pakete unterzeichnet mit ihm installieren können. Der zusätzliche Schlüssel nicht in otacerts.zip obwohl enthält, so dass Systeme , die korrekt heruntergeladenen Pakete überprüfen nicht invoke Recovery für Pakete mit diesem Schlüssel signiert.

Zertifikate und private Schlüssel

Jeder Schlüssel ist in zwei Dateien: das Zertifikat, das die Erweiterung .x509.pem hat, und der private Schlüssel, der die Erweiterung .pk8 hat. Der private Schlüssel sollte geheim gehalten werden und wird zum Signieren eines Pakets benötigt. Der Schlüssel kann selbst durch ein Passwort geschützt sein. Das Zertifikat hingegen enthält nur die öffentliche Hälfte des Schlüssels, kann also weit verbreitet werden. Es wird verwendet, um zu überprüfen, ob ein Paket mit dem entsprechenden privaten Schlüssel signiert wurde.

Das Standard - Android - Build verwendet fünf Tasten, von denen alle in residiert build/target/product/security :

Testschlüssel
Generischer Standardschlüssel für Pakete, die sonst keinen Schlüssel angeben.
Plattform
Testschlüssel für Pakete, die Teil der Kernplattform sind.
geteilt
Testschlüssel für Dinge, die im Home/Kontakte-Prozess geteilt werden.
Medien
Testschlüssel für Pakete, die Teil des Medien-/Downloadsystems sind.
Netzwerkstapel
Testschlüssel für Pakete, die Teil des Netzwerksystems sind. Die networkstack Schlüssel wird verwendet , Binärdateien , wie entworfen zu unterzeichnen Modulare Systemkomponenten . Wenn Ihre Modul-Updates separat erstellt und als vorgefertigte in Ihr Geräte-Image integriert werden, müssen Sie möglicherweise keinen Netzwerkstack-Schlüssel im Android-Quellbaum generieren.

Einzelne Pakete geben einen dieser Schlüssel an, indem sie LOCAL_CERTIFICATE in ihrer Android.mk-Datei festlegen. (testkey wird verwendet, wenn diese Variable nicht gesetzt ist.) Sie können auch einen ganz anderen Schlüssel über den Pfadnamen angeben, zB:

device/yoyodyne/apps/SpecialApp/Android.mk
 [...]

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Nun ist die Build verwendet das device/yoyodyne/security/special.{x509.pem,pk8} Schlüssel SpecialApp.apk zu unterzeichnen. Der Build kann nur private Schlüssel verwenden, die nicht passwortgeschützt.

Erweiterte Signaturoptionen

APK-Signaturschlüssel ersetzen

Die Unterzeichnung Skript sign_target_files_apks arbeitet an den Zieldateien für einen Build erzeugt. Alle Informationen zu Zertifikaten und privaten Schlüsseln, die zur Erstellungszeit verwendet werden, sind in den Zieldateien enthalten. Beim Ausführen des Signaturskripts zum Signieren für die Freigabe können Signaturschlüssel basierend auf dem Schlüsselnamen oder APK-Namen ersetzt werden.

Verwenden Sie die --key_mapping und --default_key_mappings Flaggen Schlüssel Ersatz angeben , basierend auf Schlüsselnamen:

  • Der --key_mapping src_key = dest_key Flag gibt den Ersatz für einen Schlüssel zu einem Zeitpunkt.
  • Die --default_key_mappings dir Flag gibt ein Verzeichnis mit fünf Tasten alle Schlüssel in ersetzen build/target/product/security ; es ist äquivalent zur Verwendung von --key_mapping fünfmal die Zuordnungen zu spezifizieren.
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

Verwenden Sie die --extra_apks apk_name1,apk_name2,... = key Flagge den Signaturschlüssel Ersatz auf APK Namen basierend angeben. Wenn key leer gelassen wird, wird das Skript behandelt die angegebene APKs als Pre-signiert.

Für das hypothetische tardis Produkt, müssen Sie sechs kennwortgeschützten Schlüssel: fünf die fünf in ersetzen build/target/product/security , und man den zusätzlichen Schlüssel zu ersetzen device/yoyodyne/security/special von SpecialApp im Beispiel oben erforderlich. Wenn sich die Schlüssel in den folgenden Dateien befinden:

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

Dann würden Sie alle Apps wie folgt signieren:

./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

Dies bringt folgendes hervor:

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.

Nachdem der Benutzer die Kennwörter für alle passwortgeschützten Schlüssel auffordert, das Skript erneut Zeichen alle APK - Dateien im Eingabeziel .zip mit den schlüsseln. Bevor der Befehl ausgeführt wird , können Sie auch die eingestellte ANDROID_PW_FILE Umgebungsvariable auf einen temporären Dateinamen; Das Skript ruft dann Ihren Editor auf, damit Sie Passwörter für alle Schlüssel eingeben können (dies kann eine bequemere Methode zur Eingabe von Passwörtern sein).

Austausch des APEX-Signaturschlüssels

Android 10 führen die Datei APEX - Format für untergeordnete Systemmodule zu installieren. Wie in erklärte APEX Unterzeichnung wird jede APEX - Datei mit zwei Schlüsseln signiert: ein für das Mini - Dateisystem - Image innerhalb eines APEX und die andere für die gesamte APEX.

Beim Signieren zur Freigabe werden die beiden Signaturschlüssel für eine APEX-Datei durch Freigabeschlüssel ersetzt. Das Dateisystem Payload Schlüssel werden mit dem angegebenen --extra_apex_payload Flag und der gesamten Datei Signierschlüssel APEX wird mit der angegebenen --extra_apks Flagge.

Für das tardis Produkt, vorausgesetzt , dass Sie die folgende Tastenkonfiguration für den haben com.android.conscrypt.apex , com.android.media.apex und com.android.runtime.release.apex APEX - Dateien.

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"

Und Sie haben die folgenden Dateien, die die Freigabeschlüssel enthalten:

vendor/yoyodyne/security/runtime_apex_container.x509.pem
vendor/yoyodyne/security/runtime_apex_container.pk8
vendor/yoyodyne/security/runtime_apex_payload.pem

Der folgende Befehl überschreibt die Signaturschlüssel für com.android.runtime.release.apex und com.android.tzdata.apex während der Freigabe Unterzeichnung. Insbesondere com.android.runtime.release.apex mit den angegebenen Löseschlüssel (signed runtime_apex_container für die APEX - Datei, und runtime_apex_payload für das Dateibild Nutzlast). com.android.tzdata.apex wird als vorge unterzeichnet behandelt. Alle anderen APEX-Dateien werden von der Standardkonfiguration wie in den Zieldateien aufgelistet behandelt.

./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

Wenn Sie den obigen Befehl ausführen, werden die folgenden Protokolle angezeigt:

        [...]
    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)
        [...]

Andere Optionen

Die sign_target_files_apks Unterzeichnung Skript umschreibt die Build - Beschreibung und Fingerabdruck in den Build - Eigenschaften Dateien zu reflektieren , dass der Build ist ein signierter bauen. Die --tag_changes Flag steuert , welche Änderungen an den Fingerabdruck gemacht. Führen Sie das Skript mit -h sehen Dokumentation auf allen Fahnen.

Schlüssel manuell generieren

Android Anwendungen 2048-Bit - RSA - Schlüssel mit öffentlichen Exponenten 3. Sie können Zertifikat / private Schlüsselpaare mit dem OpenSSL - Tool von generieren openssl.org :

# generate RSA key
openssl 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 key
openssl 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 key
openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt

# securely delete the temp.pem file
shred --remove temp.pem

Der openssl pkcs8 Befehl oben angegebene erstellt eine .pk8 Datei ohne Passwort, geeignet für die Verwendung mit dem Build - System. Um eine .pk8 zu erstellen mit einem Passwort gesichert (die Sie für alle aktuellen Release Tasten tun sollte), ersetzen Sie das -nocrypt Argument mit -passout stdin ; dann verschlüsselt openssl den privaten Schlüssel mit einem aus der Standardeingabe gelesenen Passwort. Es wird keine Eingabeaufforderung ausgegeben. Wenn stdin das Terminal ist, scheint das Programm zu hängen, obwohl es wirklich nur darauf wartet, dass Sie ein Passwort eingeben. Andere Werte können für das Argument-passout verwendet werden, um das Kennwort von anderen Orten zu lesen; Einzelheiten finden Sie in der OpenSSL - Dokumentation .

Die Zwischendatei temp.pem enthält den privaten Schlüssel ohne jeglichen Passwortschutz, also entsorgen Sie ihn bei der Generierung von Freigabeschlüsseln mit Bedacht. Insbesondere kann das Dienstprogramm GNShred auf Netzwerk- oder Journaled-Dateisystemen nicht effektiv sein. Sie können beim Generieren von Schlüsseln ein Arbeitsverzeichnis auf einer RAM-Disk (z. B. eine tmpfs-Partition) verwenden, um sicherzustellen, dass die Zwischenprodukte nicht versehentlich offengelegt werden.

Bilddateien erstellen

Nachdem Sie die Datei "signed-target-files.zip" erstellt haben, müssen Sie das Image erstellen, damit Sie es auf ein Gerät übertragen können. Um das signierte Image aus den Zieldateien zu erstellen, führen Sie den folgenden Befehl im Stammverzeichnis des Android-Baums aus:

img_from_target_files signed-target-files.zip signed-img.zip
Die resultierende Datei, signed-img.zip , enthält alle .img - Dateien. Um ein Bild zu laden , auf eine Vorrichtung, die Verwendung Fast Boot wie folgt:
fastboot update signed-img.zip