Podpisz kompilacje do opublikowania

Obrazy systemu operacyjnego Android używają podpisów kryptograficznych w 2 miejscach:

  1. Każdy plik .apk znajdujący się w obrazie musi być podpisany. Android Menedżer pakietów używa podpisu .apk na 2 sposoby:
    • Zastąpiona aplikacja musi być podpisana tym samym kluczem co starej aplikacji w celu uzyskania dostępu do jej danych. Zawiera true (prawda) zarówno w przypadku aktualizowania aplikacji użytkownika przez zastąpienie instrukcji .apk, jak i dla zastępując aplikację systemową nowszą wersją zainstalowaną pod /data
    • Jeśli co najmniej 2 aplikacje chcą udostępnić identyfikator użytkownika (aby dane itd.), muszą być podpisane tym samym kluczem.
  2. Pakiety aktualizacji OTA muszą być podpisane jednym z kluczy oczekiwanych przez systemu lub proces instalacji może je odrzucić.

Klawisze zwalniania

Drzewo Androida zawiera klucze-testowe w build/target/product/security Kompiluję obraz systemu operacyjnego Android użycie polecenia make spowoduje podpisanie wszystkich plików .apk za pomocą metody klawiszy testowych. Klucze testowe są publicznie znane, więc każdy może podpisać własne pliki .apk z tymi samymi kluczami, co może umożliwić ich zastąpienie lub przejęcie systemu; i aplikacjach zainstalowanych w obrazie systemu operacyjnego. Z tego powodu tak ważne jest publicznie dostępny lub wdrożony obraz systemu operacyjnego Android ze specjalnym zestawem klucze-zwolnienie, do których tylko Ty masz dostęp.

Aby wygenerować własny unikalny zestaw kluczy, uruchom te polecenia z korzenia drzewa Androida:

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 należy zmienić, aby odzwierciedlały ustawienia organizacji i informacjami o nich. Możesz użyć dowolnego katalogu, ale pamiętaj, by wybrać lokalizacji, której kopia zapasowa jest bezpieczna. Niektórzy dostawcy szyfrują dane klucz prywatny będzie zabezpieczony silnym hasłem i będzie przechowywać zaszyfrowany klucz. w ramach kontroli źródła, a inni przechowują klucze w innym miejscu, np. na komputerze bez instalacji.

Aby wygenerować obraz wersji, użyj:

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

Skrypt sign_target_files_apks pobiera pliki docelowe .zip jako dane wejściowe i tworzy nowe pliki docelowe .zip w , w którym wszystkie pliki .apk zostały podpisane nowymi kluczami. Nowy podpisane obrazy można znaleźć w domenie IMAGES/ w signed-target_files.zip

Podpisywanie pakietów OTA

Podpisany plik ZIP z plikami docelowymi można przekonwertować na podpisany plik ZIP z aktualizacją OTA korzystając z tej procedury:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

Podpisy i instalowanie z nieoficjalnych źródeł

Instalowanie z innego urządzenia nie omija normalnego podpisu pakietu odzyskiwania weryfikacji – przed zainstalowaniem pakietu funkcja odzyskiwania sprawdzi, czy jest podpisany jednym z kluczy prywatnych pasujących do kluczy publicznych przechowywanych w partycji odzyskiwania, tak jak w przypadku przesyłki dostarczanej bezprzewodowo.

Pakiety aktualizacji otrzymane z systemu głównego są zwykle weryfikowane 2 razy: przez główny system, przy użyciu RecoverySystem.verifyPackage() w interfejsie Android API, a następnie ponownie przez w celu odzyskania konta. Interfejs RecoverySystem API sprawdza podpis pod kątem kluczy publicznych przechowywane w głównym systemie, w pliku /system/etc/security/otacerts.zip (domyślnie). Odzyskiwanie sprawdza podpis pod kątem przechowywanych kluczy publicznych. na dysku RAM partycji przywracania, w pliku /res/keys.

Domyślnie pliki docelowe .zip tworzone przez kompilację ustawiają certyfikat OTA zgodny z kluczem testowym. Przy opublikowanym zdjęciu inny komponent do weryfikacji autentyczności pakietu aktualizacji. Przekazuję flagę -o do: sign_target_files_apks, tak jak w poprzedniej sekcji, zastępuje certyfikat klucza testowego z certyfikatem klucza wersji z Twoich certyfikatów katalogu.

Normalnie obraz systemu i obraz przywracania zawierają ten sam zestaw OTA. kluczy publicznych. Dodanie klucza tylko do zestawu kluczy do odzyskiwania można podpisywać pakiety, które można instalować tylko przez instalowanie z innego urządzenia (przy założeniu, że mechanizm pobierania aktualizacji głównego systemu działa prawidłowo weryfikacji za pomocą pliku otacerts.zip). Możesz określić dodatkowe klucze, uwzględnione tylko w odzyskiwaniu przez ustawienie PRODUCT_EXTRA_RECOVERY_KEYS w definicji produktu:

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

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

Obejmuje to klucz publiczny vendor/yoyodyne/security/tardis/sideload.x509.pem w trakcie przywracania kluczy, aby można było instalować pakiety podpisane z nim. Plik otacerts.zip nie zawiera jednak dodatkowego klucza, systemy, które prawidłowo weryfikują pobrane pakiety, nie wywołują opcji przywracania pakietów podpisanych tym kluczem.

Certyfikaty i klucze prywatne

Każdy klucz ma 2 pliki: certyfikat, który zawiera .x509.pem oraz klucz prywatny z rozszerzeniem .pk8. Klucz prywatny należy przechowywać w tajemnicy. Jest on potrzebny do podpisania pakietu. Klucz może być chroniona hasłem. Certyfikat w zawiera tylko publiczną połowę klucza, dzięki czemu można go rozpowszechniać bardzo szeroko. Służy do sprawdzania, czy pakiet został podpisany przez klucz prywatny.

Standardowa kompilacja Androida używa 5 kluczy, z których wszystkie są w build/target/product/security:

klucz testowy
Ogólny klucz domyślny dla pakietów, które nie określają innego klucza.
platforma
Klucz testowy dla pakietów stanowiących część podstawowej platformy.
udostępniony
Klucz do testowania elementów udostępnianych w domu/kontaktach.
multimedia
Klucz testowy dla pakietów, które są częścią systemu multimediów/pobierania.
atak sieci
Klucz testowy dla pakietów, które są częścią systemu sieciowego. klucz networktack jest używany do podpisywania plików binarnych zaprojektowanych jako Elementy systemu modułowego . Jeśli aktualizacje modułów są tworzone oddzielnie i integrowane jako gotowe może nie być konieczne generowanie klucza sieciowego w Drzewo źródłowe Androida.

Poszczególne pakiety określają jeden z tych kluczy przez ustawienie LOCAL_CERTIFICATE w pliku Android.mk. (klucz testowy jest używany, jeśli ta zmienna nie jest ustawiona). Ty Możesz też podać zupełnie inny klucz za pomocą nazwy ścieżki, na przykład:

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

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Teraz kompilacja używa klucza device/yoyodyne/security/special.{x509.pem,pk8} do podpisywania pliku SpecialApp.apk. Kompilacja może używać tylko kluczy prywatnych, które: nie są chronione hasłem.

Zaawansowane opcje podpisywania

Wymiana klucza podpisywania pliku APK

Skrypt podpisywania sign_target_files_apks działa w środowisku docelowym wygenerowanych na potrzeby kompilacji. Wszystkie informacje o certyfikatach i prywatnych klucze używane podczas kompilacji są uwzględniane w plikach docelowych. Przy uruchamianiu skrypt podpisywania do podpisania wersji, klucze podpisywania można zastąpić na podstawie klucza lub pliku APK.

--key_mapping i --default_key_mappings flagi służące do określania zastąpienia klucza na podstawie nazw kluczy:

  • Flaga --key_mapping src_key=dest_key określa zamianę 1 klucza naraz.
  • Flaga --default_key_mappings dir określa w katalogu z pięcioma kluczami, które zastąpią wszystkie klucze build/target/product/security jest odpowiednikiem --key_mapping 5 razy, aby określić mapowania.
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

Użyj Flaga --extra_apks apk_name1,apk_name2,...=key do określania zamienników kluczy podpisywania na podstawie nazw plików APK. Jeśli Pole key jest puste, skrypt traktuje określone pliki APK na wstępnie podpisanej.

W przypadku hipotetycznej usługi tardis potrzebujesz 6 kluczy chronionych hasłem: pięć, aby zastąpić pięć w grupie build/target/product/security i jeden aby zastąpić dodatkowy klucz device/yoyodyne/security/special wymagane przez SpecialApp w powyższym przykładzie. Jeśli klucze były w tych miejscach pliki:

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

Następnie podpisz wszystkie aplikacje w ten sposób:

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

Spowoduje to wyświetlenie tych informacji:

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.

Po wyświetleniu prośby o podanie haseł dla wszystkich kluczy chronionych hasłem narzędzie ponownie podpisuje wszystkie pliki APK w wejściowym miejscu docelowym .zip znakiem klawisze zwalniające. Przed uruchomieniem polecenia możesz też ustawić parametr zmienną środowiskową ANDROID_PW_FILE na nazwę pliku tymczasowego; skrypt następnie wywołuje edytor, aby umożliwić wprowadzenie haseł do wszystkich kluczy (może to być wygodniejszy sposób wpisywania haseł).

Wymiana klucza podpisywania APEX

Android 10 wprowadza Format pliku APEX do instalacji. z modułów systemowych niższego poziomu. Jak wyjaśniono w podpisywania plików APEX, podpisany dwoma kluczami: jednym dla obrazu minisystemu plików w regionie APEX oraz a inne dla całego APEX.

Podczas podpisywania wersji 2 klucze podpisywania pliku APEX są zastępowane za pomocą kluczy zwalniania. Klucz ładunku systemu plików jest określony za pomocą funkcji --extra_apex_payload, a cały klucz podpisywania pliku APEX to z flagą --extra_apks.

W przypadku usługi tardis załóżmy, że masz następującą konfigurację klucza dla com.android.conscrypt.apex, com.android.media.apex i Pliki APEX: com.android.runtime.release.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"

Masz też te pliki zawierające klucze wersji:

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

To polecenie zastępuje klucze podpisywania dla com.android.runtime.release.apex i com.android.tzdata.apex podczas podpisywania wersji. W szczególności com.android.runtime.release.apex jest podpisany(a) przy użyciu: kluczy zwalniających (runtime_apex_container dla pliku APEX oraz runtime_apex_payload dla ładunku obrazu pliku). Element com.android.tzdata.apex jest traktowany jako wstępnie podpisany. Pozostałe rynki APEX są obsługiwane zgodnie z konfiguracją domyślną podaną w plikach docelowych.

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

Uruchomienie polecenia powyżej spowoduje wyświetlenie tych dzienników:

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

Inne opcje

Skrypt podpisywania sign_target_files_apks przepisuje kompilację opis i odcisk cyfrowy w plikach właściwości kompilacji, aby pokazać, że to podpisana kompilacja. Flaga --tag_changes określa zmiany na odcisku palca. Uruchom skrypt z parametrem -h, aby zobaczyć dokumentacji dotyczącej wszystkich flag.

Ręczne generowanie kluczy

Android używa 2048-bitowych kluczy RSA z wykładnikiem publicznym 3. Możesz wygenerować par certyfikat/klucz prywatny za pomocą narzędzia opensl z 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

Podane powyżej polecenie opensl pkcs8 powoduje utworzenie pliku .pk8 z wartością no. Hasło odpowiednie do użytku z systemem kompilacji. Aby utworzyć zabezpieczony plik .pk8, i podaj hasło (które należy zrobić w przypadku wszystkich kluczy zwalniających), zastąp -nocrypt argument z -passout stdin; potem Opensl zaszyfruje klucz prywatny za pomocą hasła odczytanego ze standardowych danych wejściowych. Nie ten komunikat jest drukowany, więc jeśli terminalem jest stdin, program będzie się zawieszać. kiedy tak naprawdę czeka na Twoje wpisanie hasła. Inne wartości używany jako argument -passout do odczytu hasła z innych lokalizacji; w przypadku , zapoznaj się z Opensl.

Plik pośredni temp.pem zawiera klucz prywatny bez żadnego typu ochronę hasłem, dlatego dobrze ją wyrzuć podczas generowania wersji klawiszy. Narzędzie GNUshred może nie być skuteczne w przypadku sieci lub z systemami plików dziennika. Możesz użyć katalogu roboczego znajdującego się na dysku RAM (np. partycję tmpfs) podczas generowania kluczy, aby zapewnić, że ścieżki pośrednie nie zostały przypadkowo ujawnione.

Tworzenie plików graficznych

Gdy masz signed-target_files.zip, musisz: utworzyć obraz, aby móc go umieścić na urządzeniu. Aby utworzyć podpisany obraz z plików docelowych, uruchom polecenie to polecenie w katalogu głównym Androida drzewo:

img_from_target_files signed-target_files.zip signed-img.zip
Powstały plik signed-img.zip zawiera wszystkie pliki .img. Aby wczytać obraz na urządzenie, użyj fastboot jako następujące:
fastboot update signed-img.zip