Schemat podpisywania plików APK w wersji 3.2

Android 17 (poziom interfejsu API 37) wprowadza schemat podpisu plików APK w wersji 3.2, czyli hybrydowy schemat podpisu zaprojektowany tak, aby wspierać przejście ekosystemu Androida na kryptografię postkwantową (PQC).

W miarę jak branża wdraża algorytmy PQC na dużą skalę, schemat w wersji 3.2 zapewnia ochronę na wielu poziomach. Wymaga on podpisywania plików APK zarówno algorytmem klasycznym, takim jak RSA lub ECDSA, jak i algorytmem PQC. To hybrydowe podejście wykorzystuje kryptografię klasyczną do ochrony pliku APK, jednocześnie chroniąc przed zagrożeniami ze strony komputerów kwantowych.

Cel i szczegóły

Schemat w wersji 3.2 działa jako standardowy mechanizm przejściowy zgodny z branżą. Dzięki temu hybrydowemu podejściu zyskujesz odporność na ataki kwantowe, jaką zapewnia PQC, a jednocześnie możesz nadal korzystać ze sprawdzonego bezpieczeństwa klasycznych algorytmów podpisu. Gdy nowo znormalizowane algorytmy PQC osiągną dojrzałość operacyjną na dużą skalę, możesz przejść z tej konfiguracji hybrydowej na pojedynczy klucz podpisywania PQC. Obsługa schematu podpisu w wersji 3.2 na platformie zaczyna się od Androida 17. Starsze wersje Androida pomijają blok w wersji 3.2 i do weryfikacji podpisu używają poprzednich schematów.

Aby zachować bezpieczeństwo i zapobiec atakom polegającym na obniżeniu wersji podczas tego przejścia, schemat w wersji 3.2 wymusza następujące zachowania:

  • Nowe materiały klucza: przejście na blok hybrydowy wymaga wygenerowania nowych kluczy klasycznych i PQC. Nie używaj ponownie materiałów klucza w konfiguracjach hybrydowych i niehybrydowych.
  • Implikowana rotacja: platforma traktuje blok hybrydowy jako implikowaną rotację klucza. Platforma dołącza nowy klucz klasyczny do istniejącej historii danych podpisywania aplikacji jako przedostatni klucz i traktuje nowy klucz PQC jako bieżącą tożsamość podpisywania aplikacji.
  • Wspólna linia: aby implikowana rotacja się powiodła, zarówno nowy klucz klasyczny, jak i nowy klucz PQC w bloku hybrydowym muszą mieć tę samą linię podpisywania. Musisz skopiować dotychczasową historię podpisywania aplikacji – pojedynczy klucz oryginalny lub linię wcześniej obróconych kluczy – dla obu nowych sygnatariuszy hybrydowych. Platforma używa tej wspólnej linii, aby sprawdzić, czy podmiot, który przenosi aplikację na schemat hybrydowy, jest prawowitym właścicielem bieżącej tożsamości podpisywania aplikacji.
  • Ograniczenie dotyczące pojedynczego sygnatariusza PQC: podczas początkowego wdrażania PQC Android wyraźnie ogranicza użycie algorytmów PQC do bloku hybrydowego w wersji 3.2. Platforma nie weryfikuje konfiguracji PQC z pojedynczym sygnatariuszem przy użyciu poprzednich schematów podpisu, takich jak wersja 2, 3.0 lub 3.1.
  • Przechodzenie z powrotem: podczas przechodzenia z bloku hybrydowego w wersji 3.2 z powrotem do bloku z pojedynczym sygnatariuszem – klasycznym lub PQC, gdy będzie on obsługiwany w przyszłej wersji – platforma sprawdza, czy zarówno klucz klasyczny, jak i klucz PQC z bloku hybrydowego są obecne w nowej linii podpisywania i potwierdzają nowego pojedynczego sygnatariusza.

Sprawdzone metody przejścia

Aby zachować zgodność ze starszymi wersjami Androida i zapewnić bezpieczną ścieżkę uaktualnienia podczas przejścia na podpisywanie PQC, pliki APK muszą nadal zawierać standardowy blok podpisu w wersji 3.0 lub 3.1 podpisany pojedynczym kluczem klasycznym. Ponieważ tylko Android 17 (poziom interfejsu API 37) i nowsze obsługują schemat hybrydowy w wersji 3.2, to wymaganie umożliwia urządzeniom z niższymi wersjami weryfikowanie i instalowanie aplikacji.

Konfiguracja awaryjna klasyczna

Aby zapewnić bezpieczeństwo operacyjne podczas przejścia na PQC, wdróż konfigurację awaryjną klasyczną.

  • Istniejące aplikacje: bieżący klucz podpisywania aplikacji, K0, stanowi naturalną podstawę tej konfiguracji awaryjnej.
  • Nowe aplikacje: wygeneruj podstawowy klucz podpisywania klasycznego, K0, wraz z nowymi kluczami hybrydowymi, C_K1 i PQC_K1, aby ustalić początkową tożsamość.

W obu przypadkach plik APK musi zawierać standardowy blok podpisu w wersji 3.0 lub 3.1 podpisany kluczem klasycznym, K0, oraz blok hybrydowy w wersji 3.2 podpisany nowymi kluczami hybrydowymi, C_K1 i PQC_K1.

Podczas początkowego wdrażania schematu w wersji 3.2 linia podpisywania bloku hybrydowego powinna przyznawać kluczowi K0 uprawnienie ROLLBACK. Jeśli wystąpią problemy z wdrożeniem, to uprawnienie umożliwi aplikacji powrót do podpisu klasycznego bez zakłócania aktualizacji użytkownika. Gdy wystarczająca ilość danych z czasu działania potwierdzi, że wdrożenie hybrydowe jest stabilne, zalecamy usunięcie uprawnienia ROLLBACK w kolejnych aktualizacjach, aby w pełni zabezpieczyć nowe klucze.

Wymagania dotyczące konfiguracji długoterminowej

Musisz utrzymywać tę konfigurację podpisywania hybrydowego tak długo, jak Twoja aplikacja jest kierowana na wersję platformy, która obsługuje wyłącznie schemat hybrydowy. Nawet jeśli wersja platformy obsługuje klucze PQC z pojedynczym sygnatariuszem, musisz podpisać oba klucze dowolnym plikiem APK kierowanym na wersję, która wymaga bloku hybrydowego w wersji 3.2.

Blok schematu podpisu plików APK w wersji 3.2

Blok podpisywania plików APK przechowuje blok podpisu w wersji 3.2 wraz z blokami podpisu w wersji 2, 3.0 i 3.1.

Struktura bloku w wersji 3.2 jest podobna do wersji 3.0, ale używa nowego identyfikatora bloku, 0x70e1c89f, aby wskazać, że jest to blok hybrydowy. Prawidłowy blok w wersji 3.2 musi zawierać dokładnie 2 sygnatariuszy.

Obsługiwane algorytmy

Schemat w wersji 3.2 początkowo obsługuje te algorytmy podpisu PQC:

  • ML-DSA-65
  • ML-DSA-87

Są one połączone ze standardowymi algorytmami podpisu klasycznego, takimi jak te obsługiwane w wersjach 3.0 i 3.1, aby utworzyć blok hybrydowy.

Format

Blok podpisywania plików APK przechowuje blok schematu podpisu plików APK w wersji 3.2 pod identyfikatorem 0x70e1c89f.

Format bloku w wersji 3.2 jest identyczny z formatem w wersji 3.0, ale sekwencja elementów sygnatariusza najwyższego poziomu musi zawierać dokładnie 2 wpisy kierowane na tę samą wersję pakietu SDK:

  • sekwencja sygnatariusza z prefiksem długości:
    • sygnatariusz z prefiksem długości (klasyczny)
    • sygnatariusz z prefiksem długości (PQC)

Każdy sygnatariusz używa standardowego formatu w wersji 3:

  • dane podpisane z prefiksem długości:
    • sekwencja podsumowań z prefiksem długości:
    • identyfikator algorytmu podpisu (4 bajty)
    • podsumowanie (z prefiksem długości)
    • sekwencja certyfikatów z prefiksem długości:
    • certyfikat X.509 z prefiksem długości (format ASN.1 DER)
    • minSDK (uint32)
    • maxSDK (uint32)
    • sekwencja atrybutów dodatkowych z prefiksem długości:
    • identyfikator (uint32)
    • wartość (o zmiennej długości: długość atrybutu dodatkowego – 4 bajty)
  • minSDK (uint32)
  • maxSDK (uint32)
  • sekwencja podpisów z prefiksem długości:
    • identyfikator algorytmu podpisu (4 bajty)
    • podpis danych podpisanych z prefiksem długości
  • klucz publiczny z prefiksem długości (SubjectPublicKeyInfo, format ASN.1 DER)

Weryfikacja

W Androidzie 17 (poziom interfejsu API 37) i nowszym, aby zweryfikować podpis w wersji 3.2, platforma weryfikuje zarówno sygnatariusza klasycznego, jak i PQC, potwierdza ich zgodność i sprawdza linię implikowanej rotacji. W wersjach platformy Android 16 (poziom interfejsu API 36) i starszych platforma nie przetwarza tego bloku podpisu hybrydowego i zamiast tego używa poprzednich schematów.

Ogólny proces wygląda tak:

  1. Znajdź blok schematu podpisu plików APK w wersji 3.2 (identyfikator 0x70e1c89f).
  2. Sprawdź, czy blok zawiera dokładnie 2 sygnatariuszy. Jeśli jest ich mniej lub więcej niż 2, weryfikacja się nie powiedzie.
  3. Sprawdź, czy jeden sygnatariusz używa algorytmu podpisu klasycznego, a drugi – algorytmu podpisu PQC. Jeśli oba są klasyczne lub oba są PQC, weryfikacja się nie powiedzie.
  4. Sprawdź, czy obaj sygnatariusze są kierowani na ten sam zakres pakietu SDK (minSdkVersion i maxSdkVersion).
  5. W przypadku każdego z 2 sygnatariuszy przeprowadź standardową weryfikację w wersji 3:
    1. Wybierz najsilniejszy obsługiwany identyfikator algorytmu podpisu z podpisów.
    2. Zweryfikuj odpowiedni podpis z podpisów względem danych podpisanych za pomocą klucza publicznego.
    3. Sprawdź, czy wartości minSdkVersion i maxSdkVersion w danych podpisanych są zgodne z wartościami minSdkVersion i maxSdkVersion bez podpisu.
    4. Przeanalizuj certyfikaty i sprawdź, czy pierwszy certyfikat pasuje do klucza publicznego.
    5. Przeanalizuj atrybuty dodatkowe, aby wyodrębnić struktury potwierdzające rotację.
  6. Sprawdź historię podpisywania (potwierdzenie rotacji):
    1. Sprawdź, czy obaj sygnatariusze mają identyczną historię podpisywania.
    2. Długości historii danych muszą być zgodne, a wszystkie certyfikaty i flagi uprawnień prowadzące do bieżących sygnatariuszy muszą być identyczne.
    3. Jeśli historie są zgodne, scal linie: traktuj certyfikat sygnatariusza klasycznego jako poprzednika certyfikatu sygnatariusza PQC, przypisując sygnatariusza PQC jako bieżący węzeł końcowy.
  7. Sprawdź podsumowania treści:
    1. Przejdź przez mapę podsumowań dla obu sygnatariuszy.
    2. Sprawdź, czy w przypadku pasujących algorytmów podsumowań obliczone wartości podsumowań są identyczne dla sygnatariuszy klasycznych i PQC.
  8. Użyj dopasowanych podsumowań od zweryfikowanych sygnatariuszy, aby sprawdzić integralność zawartości pliku APK (podobnie jak w przypadku wersji 2 i 3).
    1. Jeśli aplikacja jest już zainstalowana, sprawdź linię aktualizacji pakietu:
    2. Aktualizowanie z pojedynczego sygnatariusza: jeśli zainstalowana aplikacja została podpisana pojedynczym kluczem klasycznym, ten klucz musi być obecny w linii podpisywania nowego bloku hybrydowego jako poprzednik sygnatariuszy hybrydowych.
    3. Aktualizowanie z sygnatariusza hybrydowego w celu kontynuowania hybrydy: jeśli zainstalowana aplikacja została podpisana blokiem hybrydowym w wersji 3.2, zarówno poprzedni klucz klasyczny, jak i klucz PQC muszą pozostać bieżącymi aktywnymi sygnatariuszami w bloku w wersji 3.2 pliku APK aktualizacji lub oba muszą być obecne w nowej linii podpisywania potwierdzającej nowo obrócone klucze hybrydowe.
    4. Przechodzenie z sygnatariusza hybrydowego: jeśli zainstalowana aplikacja została podpisana blokiem hybrydowym w wersji 3.2, a plik APK aktualizacji wraca do pojedynczego sygnatariusza (PQC lub klasycznego), obaj poprzedni sygnatariusze hybrydowi muszą być obecni w linii podpisywania pliku APK aktualizacji i potwierdzać nowy pojedynczy klucz podpisywania.
    5. Nieprawidłowe ścieżki aktualizacji: jeśli deweloper spróbuje zaktualizować aplikację podpisaną hybrydowo, używając tylko jednego z kluczy hybrydowych jako pojedynczego sygnatariusza bez prawidłowej rotacji, aktualizacja się nie powiedzie. Aby zapobiec atakom polegającym na obniżeniu wersji, oba klucze muszą być wyraźnie uwzględnione w każdym przejściu.
  9. Jeśli którykolwiek krok się nie powiedzie, weryfikacja się nie powiedzie.

Zabezpieczenie przed usuwaniem

Aby zapobiec atakom polegającym na obniżeniu wersji do starszych schematów podpisu, schemat w wersji 3.2 zawiera atrybuty ochrony przed usuwaniem podobne do poprzednich wersji schematu.

Narzędzie do podpisywania zapisuje 2 konkretne atrybuty ochrony przed usuwaniem hybrydowym w atrybutach dodatkowych bloków podpisu w wersji 3.0 i 3.1. Te atrybuty określają dokładne granice wersji pakietu SDK, w których blok hybrydowy w wersji 3.2 musi być obecny i zweryfikowany:

  • Atrybut minimalnej wersji pakietu SDK (identyfikator 0xbf940529): wartość tego atrybutu określa minimalną wersję pakietu SDK obsługiwaną przez blok podpisywania hybrydowego.
  • Atrybut maksymalnej wersji pakietu SDK (identyfikator 0x9f06b79c): wartość tego atrybutu określa maksymalną wersję pakietu SDK obsługiwaną przez blok podpisywania hybrydowego. Ten atrybut umożliwia przejście na konfigurację z pojedynczym sygnatariuszem, gdy nowsze wersje platformy nie wymagają podpisu hybrydowego.

Jeśli platforma pominie weryfikację w wersji 3.2, ponieważ blok jest nieobecny lub jego zakres pakietu SDK nie ma zastosowania do urządzenia, platforma zweryfikuje plik APK względem następnego bloku. Jeśli ten wcześniejszy blok zawiera te atrybuty ochrony przed usuwaniem, platforma zastosuje te sprawdzenia:

  • Sprawdzanie obecności i zakresu: jeśli blok podpisu w wersji 3.0 lub 3.1 zawiera atrybut minimalnej wersji pakietu SDK (identyfikator 0xbf940529, wartość X) lub atrybut maksymalnej wersji pakietu SDK (identyfikator 0x9f06b79c, wartość Y), platforma wymaga, aby w pliku APK znajdował się blok hybrydowy w wersji 3.2. Platforma odczytuje blok hybrydowy, aby sprawdzić, czy jego docelowy zakres pakietu SDK jest zgodny z granicami określonymi przez te atrybuty. Jeśli blok w wersji 3.2 jest nieobecny lub jeśli jego wewnętrzne wartości minimalnej i maksymalnej wersji pakietu SDK nie są równe X i Y, platforma odrzuci instalację.
  • Wymuszanie w zakresie: jeśli wersja pakietu SDK urządzenia mieści się w prawidłowym zakresie określonym przez te atrybuty – czyli jest większa lub równa X i mniejsza lub równa Y, gdy podasz atrybut maksymalny – platforma ściśle wymaga bloku hybrydowego w wersji 3.2 do weryfikacji podpisu. Jeśli platforma zweryfikuje blok w wersji 3.0 lub 3.1 na urządzeniu w tym docelowym zakresie pakietu SDK, odrzuci instalację, ponieważ blok w wersji 3.2 został złośliwie pominięty lub usunięty.

Wymuszając te granice, platforma określa, kiedy plik APK musi zawierać blok w wersji 3.2. Jeśli blok został usunięty, platforma odrzuci instalację, aby zapobiec atakowi polegającemu na obniżeniu wersji.

Sprawdzanie poprawności implementacji

Aby przetestować implementację schematu podpisu w wersji 3.2, uruchom testy CTS HybridSignatureVerificationTest.java znajdujące się w cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.

Testy te obejmują kompleksowy zestaw scenariuszy, w tym udane instalacje, aktualizacje z wersji tylko klasycznych, przejścia z powrotem za pomocą uprawnienia ROLLBACK oraz weryfikacje środków zapobiegających atakom polegającym na usuwaniu.