Podpisywanie aplikacji umożliwia deweloperom identyfikację autora aplikacji i jej aktualizowanie bez tworzenia skomplikowanych interfejsów i uprawnień. Każda aplikacja uruchomiona na platformie Androida musi być podpisana przez dewelopera. Aplikacje, które próbują się zainstalować bez podpisu, są odrzucane przez Google Play lub instalator pakietu na urządzeniu z Androidem.
W Google Play podpisywanie aplikacji łączy zaufanie Google z deweloperem oraz zaufanie deweloperskie do ich aplikacji. Deweloperzy wiedzą, że ich aplikacja jest udostępniana na urządzeniu z Androidem, niezmodyfikowana, a programiści ponoszą odpowiedzialność za swoje działania.
Na Androidzie podpisanie aplikacji jest pierwszym krokiem do umieszczenia jej w sandboksie aplikacji. Podpisany certyfikat aplikacji określa, który identyfikator użytkownika jest powiązany z daną aplikacją. Poszczególne aplikacje działają z różnymi identyfikatorami użytkowników. Dzięki podpisywaniu aplikacji żadna z nich nie ma dostępu do żadnej innej aplikacji (chyba że korzystasz z dobrze zdefiniowanego protokołu IPC).
Gdy aplikacja (plik APK) jest zainstalowana na urządzeniu z Androidem, menedżer pakietów sprawdza, czy plik APK został poprawnie podpisany certyfikatem zawartym w tym pliku APK. Jeśli certyfikat (a ściślej rzecz biorąc klucz publiczny w certyfikacie) pasuje do klucza użytego do podpisania dowolnego innego pliku APK na urządzeniu, nowy plik APK może w manifeście określić, że ma ten sam identyfikator UID co inne podpisane w taki sam sposób pliki APK.
Aplikacje mogą być podpisane przez inną firmę (OEM, operatora, alternatywny rynek) lub przez siebie. Android umożliwia podpisywanie kodu przy użyciu samodzielnie podpisanych certyfikatów, które deweloperzy mogą generować bez pomocy i zgody z zewnątrz. Aplikacje nie muszą być podpisane przez urząd centralny. Obecnie w przypadku certyfikatów aplikacji Android nie przeprowadza weryfikacji urzędu certyfikacji.
Aplikacje mogą też deklarować uprawnienia zabezpieczające na poziomie ochrony podpisu, ograniczając dostęp tylko do aplikacji podpisanych tym samym kluczem, przy zachowaniu odrębnych identyfikatorów UID i piaskownic aplikacji. Współdzielenie piaskownicy aplikacji jest możliwe dzięki funkcji udostępniania identyfikatora UID, która umożliwia zadeklarowanie w pliku manifestu wspólnego identyfikatora UID przez co najmniej 2 aplikacje podpisane tym samym kluczem dewelopera.
Schematy podpisywania plików APK
Android obsługuje 3 schematy podpisywania aplikacji:
- Schemat v1: na podstawie podpisywania pliku JAR
- Schemat w wersji 2: schemat podpisu pliku APK w wersji 2, który został wprowadzony w Androidzie 7.0.
- Schemat w wersji 3: schemat podpisu pliku APK w wersji 3, który został wprowadzony w Androidzie 9.
Aby uzyskać maksymalną zgodność, podpisuj aplikacje wszystkimi schematami, najpierw w wersji 1, potem 2, a następnie 3. Urządzenia z Androidem 7.0 lub nowszym instalują aplikacje podpisane przy użyciu schematów w wersji 2 lub nowszej szybciej niż te podpisane tylko przy użyciu schematu w wersji 1. Starsze platformy Androida ignorują podpisy w wersji 2 i późniejszych, dlatego aplikacje muszą zawierać podpisy w wersji 1.
Podpisywanie JAR (schemat w wersji 1)
Podpisywanie plików APK jest częścią Androida od samego początku. Opiera się on na podpisanym pliku JAR. Szczegółowe informacje o korzystaniu z tego schematu znajdziesz w dokumentacji Androida Studio poświęconej podpisywaniu aplikacji.
Podpisy w wersji 1 nie chronią niektórych części pliku APK, takich jak metadane ZIP. Weryfikator plików APK musi przetworzyć wiele niezaufanych (jeszcze niezweryfikowanych) struktur danych, a następnie odrzucić dane, których nie obejmują podpisy. To tworzy znaczną powierzchnię ataku. Ponadto weryfikator pliku APK musi rozpakować wszystkie skompresowane wpisy, co wymaga więcej czasu i pamięci. Aby rozwiązać te problemy, w Androidzie 7.0 wprowadzono schemat podpisu plików APK w wersji 2.
Schemat podpisu pliku APK w wersji 2 i 3 (schemat w wersji 2+
Urządzenia z Androidem 7.0 i nowszym obsługują schemat podpisywania plików APK w wersji 2 (schemat w wersji 2) i nowszych. (w Androidzie 9 schemat w wersji 2 został zaktualizowany do wersji 3, aby uwzględnić dodatkowe informacje w bloku podpisywania, ale w pozostałości działa tak samo). Treść pliku APK jest zaszyfrowana i podpisana, a potem do pliku APK jest wstawiany blok podpisywania. Szczegółowe informacje na temat stosowania schematu w wersji 2+ do aplikacji znajdziesz w artykule Schemat podpisu pliku APK w wersji 2.
Podczas weryfikacji schemat v2+ traktuje plik APK jako blob i sprawdza podpis w całym pliku. Wszelkie modyfikacje pliku APK, w tym modyfikacje metadanych pliku ZIP, powodują unieważnienie podpisu pliku APK. Ta forma weryfikacji APK jest znacznie szybsza i umożliwia wykrywanie większej liczby nieautoryzowanych modyfikacji.
Nowy format jest zgodny ze starszymi wersjami, więc pliki APK podpisane przy użyciu nowego formatu podpisu można instalować na starszych urządzeniach z Androidem (które po prostu ignorują dodatkowe dane dodane do pliku APK), o ile są one również podpisane w wersji 1.
Cały plik APK jest weryfikowany pod kątem podpisu w wersji 2+ przechowywanego w bloku podpisywania pliku APK. Hash obejmuje wszystko oprócz bloku podpisywania pliku APK, który zawiera podpis w wersji 2+. Wszelkie modyfikacje pliku APK poza blokiem podpisywania plików APK powodują unieważnienie podpisu pliku APK w wersji 2 lub nowszej. Pliki APK z usuniętym podpisem w wersji 2 lub nowszej są również odrzucane, ponieważ ich podpis w wersji 1 wskazuje, że plik APK został podpisany w wersji 2, co powoduje, że Android w wersji 7.0 lub nowszej odmawia weryfikacji plików APK przy użyciu podpisów w wersji 1.
Szczegółowe informacje o procesie weryfikacji podpisu pliku APK znajdziesz w sekcji Weryfikacja w schemacie podpisu pliku APK w wersji 2.