Schemat podpisu APK v3

Android 9 obsługuje rotację kluczy APK , co daje aplikacjom możliwość zmiany klucza podpisywania w ramach aktualizacji APK. Aby rotacja była praktyczna, pliki APK muszą wskazywać poziomy zaufania między nowym i starym kluczem podpisywania. Aby obsługiwać rotację kluczy, zaktualizowaliśmy schemat podpisu APK z wersji 2 do wersji 3, aby umożliwić użycie nowych i starych kluczy. Wersja 3 dodaje informacje o obsługiwanych wersjach zestawu SDK i strukturze dowodu rotacji do bloku podpisywania pliku APK.

Blok podpisywania APK

Aby zachować kompatybilność wsteczną z formatem APK v1, podpisy APK v2 i v3 są przechowywane w bloku podpisu APK, znajdującym się bezpośrednio przed centralnym katalogiem ZIP.

Format bloku podpisywania pliku APK w wersji 3 jest taki sam jak w wersji 2 . Podpis v3 pakietu APK jest przechowywany jako para identyfikator-wartość o identyfikatorze 0xf05368c0.

Blok schematu podpisu APK v3

Schemat v3 został zaprojektowany tak, aby był bardzo podobny do schematu v2 . Ma ten sam ogólny format i obsługuje te same identyfikatory algorytmów podpisu , rozmiary kluczy i krzywe EC.

Jednak schemat v3 dodaje informacje o obsługiwanych wersjach zestawu SDK i strukturze dowodu rotacji.

Format

Blok schematu podpisu APK v3 jest przechowywany w bloku podpisu APK pod identyfikatorem 0xf05368c0 .

Format bloku schematu podpisu APK v3 jest zgodny z formatem v2:

  • sekwencja signer z przedrostkiem długości:
    • signed data z prefiksem długości:
      • sekwencja skrótów z digests długości:
        • signature algorithm ID (4 bajty)
        • digest (z przedrostkiem długości)
      • sekwencja certificates X.509 z prefiksem długości:
        • certificate X.509 z prefiksem długości (formularz ASN.1 DER)
      • minSDK (uint32) - ten podpisujący powinien zostać zignorowany, jeśli wersja platformy jest niższa od tego numeru.
      • maxSDK (uint32) - ten podpisujący powinien zostać zignorowany, jeśli wersja platformy jest powyżej tego numeru.
      • sekwencja additional attributes z przedrostkiem długości:
        • ID (uint32)
        • value (zmienna długość: długość dodatkowego atrybutu - 4 bajty)
        • ID - 0x3ba06f8c
        • value - struktura dowodu rotacji
    • minSDK (uint32) - duplikat wartości minSDK w sekcji podpisanych danych - używany do pominięcia weryfikacji tego podpisu, jeśli bieżąca platforma nie jest w zasięgu. Musi odpowiadać podpisanej wartości danych.
    • maxSDK (uint32) - duplikat wartości maxSDK w sekcji podpisanych danych - używany do pominięcia weryfikacji tego podpisu, jeśli bieżąca platforma nie jest w zasięgu. Musi odpowiadać podpisanej wartości danych.
    • sekwencja signatures z przedrostkiem długości:
      • signature algorithm ID (uint32)
      • signature z przedrostkiem długości nad signed data
    • public key z prefiksem długości (SubjectPublicKeyInfo, formularz ASN.1 DER)

Struktury potwierdzające rotację i stare certyfikaty zaufania

Struktura dowodu rotacji umożliwia aplikacjom obracanie certyfikatów podpisu bez blokowania ich w innych aplikacjach, z którymi się komunikują. Aby to osiągnąć, podpisy aplikacji zawierają dwa nowe elementy danych:

  • zapewnienie stronom trzecim, że certyfikatowi podpisywania aplikacji można ufać wszędzie tam, gdzie ufa się jego poprzednikom
  • starsze certyfikaty podpisywania aplikacji, którym sama aplikacja nadal ufa

Atrybut dowodu rotacji w sekcji podpisanych danych składa się z listy z pojedynczym łączem, przy czym każdy węzeł zawiera certyfikat podpisywania używany do podpisywania poprzednich wersji aplikacji. Ten atrybut ma zawierać struktury danych koncepcyjnego dowodu rotacji i zaufanych starych certyfikatów. Lista jest uporządkowana według wersji z najstarszym certyfikatem podpisującym odpowiadającym węzłowi głównemu. Strukturę danych potwierdzającą rotację buduje się w ten sposób, że certyfikat w każdym węźle podpisuje następny na liście, a tym samym nasyca każdy nowy klucz dowodem, że powinien być tak samo godny zaufania jak starszy klucz(e).

Struktura danych typu self-trust-old-certs jest tworzona poprzez dodanie do każdego węzła flag wskazujących jego przynależność i właściwości do zbioru. Na przykład może być obecna flaga wskazująca, że ​​certyfikat podpisywania w danym węźle jest zaufany w zakresie uzyskiwania uprawnień do podpisu Androida. Ta flaga pozwala innym aplikacjom podpisanym przy użyciu starszego certyfikatu nadal uzyskiwać uprawnienia do podpisywania zdefiniowane przez aplikację podpisaną przy użyciu nowego certyfikatu podpisywania. Ponieważ cały atrybut dowodu rotacji znajduje się w sekcji podpisanych danych pola signer w wersji 3, jest on chroniony kluczem używanym do podpisania zawierającego go pliku APK.

Ten format wyklucza wiele kluczy podpisujących i zbieżność różnych certyfikatów podpisujących przodków w jeden (wiele węzłów początkowych do wspólnego ujścia).

Format

Dowód rotacji jest przechowywany w bloku APK Signature Scheme v3 pod identyfikatorem 0x3ba06f8c . Jego format to:

  • sekwencja levels z przedrostkiem długości:
    • signed data z prefiksem długości (według poprzedniego certyfikatu - jeśli istnieje)
      • certificate X.509 z prefiksem długości (formularz ASN.1 DER)
      • signature algorithm ID (uint32) - algorytm używany przez certyfikat na poprzednim poziomie
    • flags (uint32) - flagi wskazujące, czy ten certyfikat powinien znajdować się w strukturze starych certyfikatów zaufania i dla jakich operacji.
    • signature algorithm ID (uint32) - musi być zgodny z tym z sekcji podpisanych danych na kolejnym poziomie.
    • signature z przedrostkiem długości nad powyższymi signed data

Wiele certyfikatów

Obecnie system Android traktuje plik APK podpisany wieloma certyfikatami jako posiadający unikalną tożsamość podpisu odrębną od składających się na niego certyfikatów. Zatem atrybut dowodu rotacji w sekcji podpisanych danych tworzy ukierunkowany graf acykliczny, który można lepiej postrzegać jako listę z pojedynczym łączem, w której każdy zestaw sygnatariuszy danej wersji reprezentuje jeden węzeł. Zwiększa to dodatkową złożoność struktury dowodu rotacji (wersja z wieloma podpisami poniżej). W szczególności problemem staje się zamawianie. Co więcej, nie jest już możliwe niezależne podpisywanie plików APK, ponieważ struktura dowodu rotacji musi uwzględniać stare certyfikaty podpisywania podpisujące nowy zestaw certyfikatów, a nie podpisywanie ich jeden po drugim. Na przykład plik APK podpisany kluczem A, który chce być podpisany dwoma nowymi kluczami B i C, nie może zawierać podpisu B po prostu podpisu A lub B, ponieważ jest to inna tożsamość podpisu niż B i C. To mogłoby oznacza, że ​​sygnatariusze muszą skoordynować działania przed zbudowaniem takiej struktury.

Atrybut potwierdzający rotację wielu sygnatariuszy

  • sekwencja sets z przedrostkiem długości :
    • signed data (według poprzedniego zestawu - jeśli istnieje)
      • sekwencja certificates z przedrostkiem długości
        • certificate X.509 z prefiksem długości (formularz ASN.1 DER)
      • Kolejność signature algorithm IDs (uint32) - po jednym dla każdego certyfikatu z poprzedniego zestawu, w tej samej kolejności.
    • flags (uint32) - flagi wskazujące, czy ten zestaw certyfikatów powinien znajdować się w strukturze starych certyfikatów zaufania i dla jakich operacji.
    • sekwencja signatures z przedrostkiem długości:
      • signature algorithm ID (uint32) - musi być zgodny z tym z sekcji podpisanych danych
      • signature z przedrostkiem długości nad powyższymi signed data

Wielu przodków w strukturze dowodu rotacji

Schemat v3 również nie obsługuje dwóch różnych kluczy zmienianych na ten sam klucz podpisywania dla tej samej aplikacji. Różni się to od przypadku przejęcia, w którym firma przejmująca chciałaby przenieść nabytą aplikację, aby używać jej klucza podpisującego do udostępniania uprawnień. Przejęcie jest postrzegane jako obsługiwany przypadek użycia, ponieważ nowa aplikacja będzie wyróżniać się nazwą pakietu i może zawierać własną strukturę potwierdzającą rotację. Nieobsługiwany przypadek, w którym ta sama aplikacja ma dwie różne ścieżki dostępu do tego samego certyfikatu, łamie wiele założeń przyjętych w projekcie rotacji kluczy.

Weryfikacja

W systemie Android 9 i nowszych wersjach pliki APK można weryfikować zgodnie ze schematem podpisu APK v3, v2 lub v1. Starsze platformy ignorują podpisy v3 i próbują zweryfikować podpisy v2, a następnie v1.

Proces weryfikacji podpisu APK

Rysunek 1. Proces weryfikacji podpisu APK

Weryfikacja schematu podpisu APK v3

  1. Znajdź blok podpisywania pliku APK i sprawdź, czy:
    1. Dwa pola rozmiaru bloku podpisywania APK zawierają tę samą wartość.
    2. Bezpośrednio po ZIP Central Directory następuje rekord ZIP End of Central Directory.
    3. Po zakończeniu ZIP Central Directory nie następuje więcej danych.
  2. Znajdź pierwszy blok schematu podpisu APK v3 wewnątrz bloku podpisywania APK. Jeśli obecny jest blok v3, przejdź do kroku 3. W przeciwnym razie wróć do weryfikacji pliku APK przy użyciu schematu v2 .
  3. Dla każdego signer w bloku schematu podpisów APK v3 z minimalną i maksymalną wersją pakietu SDK mieszczącą się w zakresie bieżącej platformy:
    1. Wybierz najsilniejszy obsługiwany signature algorithm ID z signatures . Kolejność mocy zależy od każdej wersji implementacji/platformy.
    2. Zweryfikuj odpowiedni signature z signatures względem signed data przy użyciu public key . (Teraz można bezpiecznie analizować signed data .)
    3. Sprawdź, czy minimalna i maksymalna wersja zestawu SDK w podpisanych danych jest zgodna z wersją określoną dla signer .
    4. Sprawdź, czy uporządkowana lista identyfikatorów algorytmów podpisu w digests i signatures jest identyczna. (Zapobiega to usuwaniu/dodawaniu podpisów.)
    5. Oblicz skrót zawartości APK , używając tego samego algorytmu skrótu, co algorytm skrótu używany przez algorytm podpisu.
    6. Sprawdź, czy obliczone podsumowanie jest identyczne z odpowiadającym digests digest
    7. Sprawdź, czy SubjectPublicKeyInfo pierwszego certificate certificates jest identyczny z public key .
    8. Jeśli dla signer istnieje atrybut dowodu rotacji, sprawdź, czy struktura jest prawidłowa i czy ten signer jest ostatnim certyfikatem na liście.
  4. Weryfikacja przebiegła pomyślnie, jeśli w zasięgu bieżącej platformy został znaleziony dokładnie jeden signer i dla tego signer powiódł się krok 3.

Walidacja

Aby sprawdzić, czy Twoje urządzenie poprawnie obsługuje wersję 3, uruchom testy PkgInstallSignatureVerificationTest.java CTS w cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ .