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, pakiety APK muszą wskazywać poziomy zaufania między nowym a starym kluczem podpisywania. Aby obsługiwać rotację kluczy, zaktualizowaliśmy schemat sygnatur APK z wersji 2 do wersji 3, aby umożliwić korzystanie z nowych i starych kluczy. Wersja 3 dodaje informacje o obsługiwanych wersjach SDK i strukturę dowodu rotacji do bloku podpisywania APK.

Blok podpisywania APK

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

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

Blok schematu podpisu APK v3

Schemat v3 jest 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 podpisywania APK pod identyfikatorem 0xf05368c0 .

Format bloku APK Signature Scheme v3 jest zgodny z formatem v2:

  • Sekwencja signer z prefiksem długości z prefiksem długości :
    • signed data z prefiksem długości :
      • sekwencja skrótów z przedrostkiem długości z przedrostkiem digests :
        • signature algorithm ID (4 bajty)
        • digest (z przedrostkiem długości)
      • ciąg certificates X.509 z prefiksem długości :
        • certificate X.509 z prefiksem długości (formularz ASN.1 DER)
      • minSDK (uint32) — ta osoba podpisująca powinna zostać zignorowana, jeśli wersja platformy jest niższa od tej liczby.
      • maxSDK (uint32) — ten podpisujący powinien zostać zignorowany, jeśli wersja platformy jest wyższa od tej liczby.
      • Sekwencja z przedrostkiem długości additional attributes z przedrostkiem długości :
        • ID (uint32)
        • value (variable-length: długość dodatkowego atrybutu - 4 bajty)
        • ID - 0x3ba06f8c
        • value - struktura dowodu rotacji
    • minSDK (uint32) - duplikat wartości minSDK w sekcji podpisanych danych - służy do pomijania weryfikacji tego podpisu, jeśli bieżąca platforma jest poza zasięgiem. Musi pasować do podpisanej wartości danych.
    • maxSDK (uint32) - duplikat wartości maxSDK w sekcji podpisanych danych - służy do pominięcia weryfikacji tego podpisu, jeśli bieżąca platforma nie jest w zasięgu. Musi pasować do podpisanej wartości danych.
    • sekwencja signatures z przedrostkiem długości :
      • signature algorithm ID (uint32)
      • signature z prefiksem długości nad signed data
    • public key z prefiksem długości (SubjectPublicKeyInfo, formularz ASN.1 DER)

Dowód rotacji i zaufane stare struktury certyfikatów

Struktura dowód rotacji umożliwia aplikacjom obracanie certyfikatu podpisywania bez blokowania w innych aplikacjach, z którymi się komunikują. Aby to osiągnąć, podpisy aplikacji zawierają dwie nowe porcje danych:

  • zapewnienie stronom trzecim, że certyfikat podpisywania aplikacji może być zaufany wszędzie tam, gdzie ufają jego poprzednicy
  • starsze certyfikaty podpisywania aplikacji, którym sama aplikacja nadal ufa

Atrybut proof-of-rotation w sekcji podpisanych danych składa się z pojedynczej połączonej listy, przy czym każdy węzeł zawiera certyfikat podpisywania używany do podpisywania poprzednich wersji aplikacji. Ten atrybut ma zawierać koncepcyjne struktury danych dowodu rotacji i zaufane-stare-certyfikaty. Lista jest uporządkowana według wersji z najstarszym certyfikatem podpisu odpowiadającym węzłowi głównemu. Struktura danych dowodu rotacji jest budowana przez to, że certyfikat w każdym węźle podpisuje następny na liście, a tym samym nasyca każdy nowy klucz dowodami, że powinien być tak samo zaufany, jak starszy klucz (klucze).

Struktura danych self-trusted-old-certs jest tworzona przez dodanie flag do każdego węzła, wskazujących jego członkostwo i właściwości w zestawie. 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 systemu Android. Ta flaga pozwala innym aplikacjom podpisanym starszym certyfikatem nadal otrzymywać uprawnienia do podpisu zdefiniowane przez aplikację podpisaną przy użyciu nowego certyfikatu do podpisywania. Ponieważ cały atrybut proof-of-rotation znajduje się w podpisanej sekcji danych pola signer w wersji 3, jest chroniony przez klucz używany do podpisywania zawierającego apk.

Ten format wyklucza wielokrotne klucze podpisywania i zbieżność różnych certyfikatów podpisywania przodków w jednym (wiele początkowych węzłów do wspólnego ujścia).

Format

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

  • ciąg 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 cert na poprzednim poziomie
    • flags (uint32) - flagi wskazujące, czy ten certyfikat powinien znajdować się w strukturze self-trusted-old-certs i dla jakich operacji.
    • signature algorithm ID (uint32) - musi być zgodny z tym z sekcji podpisanych danych na następnym poziomie.
    • signature z prefiksem długości nad powyższymi signed data

Wiele certyfikatów

Android obecnie traktuje plik APK podpisany wieloma certyfikatami jako posiadający unikalną tożsamość podpisywania, odrębną od certyfikatów składających się na niego. W ten sposób atrybut dowodu rotacji w sekcji danych podpisanych tworzy ukierunkowany graf acykliczny, który można lepiej postrzegać jako pojedynczo połączoną listę, w której każdy zestaw osób podpisujących dla danej wersji reprezentuje jeden węzeł. Zwiększa to dodatkową złożoność struktury dowodu rotacji (wersja z wieloma sygnatariuszami poniżej). W szczególności problemem staje się zamawianie. Co więcej, nie jest już możliwe samodzielne podpisywanie pakietów APK, ponieważ struktura dowodu rotacji musi mieć stare certyfikaty podpisywania, które podpisują nowy zestaw certyfikatów, zamiast podpisywać je pojedynczo. Na przykład plik APK podpisany kluczem A, który chce być podpisany przez dwa nowe klucze B i C, nie może wymagać, aby osoba podpisująca B zawierała tylko podpis A lub B, ponieważ jest to inna tożsamość podpisu niż B i C. oznacza, że ​​sygnatariusze muszą koordynować przed zbudowaniem takiej struktury.

Atrybut potwierdzenia rotacji wielu sygnatariuszy

  • ciąg z przedrostkiem długości sets z przedrostkiem długości :
    • signed data (według poprzedniego zestawu - jeśli istnieje)
      • ciąg certificates z prefiksem 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 self-trusted-old-certs 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 prefiksem 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 obracających się do tego samego klucza podpisywania dla tej samej aplikacji. Inaczej jest w przypadku przejęcia, w którym firma przejmująca chciałaby przenieść przejętą aplikację, aby używać jej klucza podpisu do udostępniania uprawnień. Przejęcie jest postrzegane jako obsługiwany przypadek użycia, ponieważ nowa aplikacja byłaby wyróżniana na podstawie nazwy pakietu i mogłaby zawierać własną strukturę dowodu rotacji. Nieobsługiwany przypadek tej samej aplikacji, która ma dwie różne ścieżki do tego samego certyfikatu, łamie wiele założeń przyjętych w projekcie rotacji kluczy.

Weryfikacja

W systemie Android 9 i nowszych pakiety APK można zweryfikować zgodnie ze schematem APK Signature Scheme 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 APK i sprawdź, czy:
    1. Dwa pola rozmiaru bloku podpisywania APK zawierają tę samą wartość.
    2. Bezpośrednio po katalogu centralnym ZIP następuje wpis Koniec katalogu centralnego ZIP.
    3. Po zakończeniu ZIP centralnego katalogu nie następuje więcej danych.
  2. Znajdź pierwszy blok schematu podpisu APK v3 w bloku podpisywania APK. Jeśli blok v3 jest obecny, przejdź do kroku 3. W przeciwnym razie wróć do weryfikacji APK przy użyciu schematu v2 .
  3. Dla każdego signer w APK Signature Scheme v3 Block z minimalną i maksymalną wersją SDK, która znajduje się w zakresie bieżącej platformy:
    1. Wybierz najsilniejszy obsługiwany signature algorithm ID podpisu spośród signatures . Kolejność siły zależy od każdej wersji wdrożenia/platformy.
    2. Zweryfikuj odpowiedni signature z signatures z signed data przy użyciu public key . (Teraz można bezpiecznie analizować signed data .)
    3. Sprawdź, czy minimalna i maksymalna wersja pakietu SDK w podpisanych danych są zgodne z określonymi dla osoby signer .
    4. Sprawdź, czy uporządkowana lista identyfikatorów algorytmów podpisu w digests i signatures jest identyczna. (Ma to na celu zapobieganie usuwaniu/dodawaniu podpisu).
    5. Oblicz skrót zawartości APK przy użyciu tego samego algorytmu skrótu, co algorytm skrótu używany przez algorytm podpisu.
    6. Sprawdź, czy obliczony digest jest identyczny z odpowiadającym mu skrótem ze digests .
    7. Sprawdź, czy SubjectPublicKeyInfo pierwszego certificate certificates jest identyczny z public key .
    8. Jeśli atrybut dowód rotacji istnieje dla osoby signer , sprawdź, czy struktura jest prawidłowa, a signer jest ostatnim certyfikatem na liście.
  4. Weryfikacja zakończy się pomyślnie, jeśli w zasięgu bieżącej platformy zostanie znaleziony dokładnie jeden signer , a krok 3 powiódł się dla tego signer .

Walidacja

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