Podpisywanie aplikacji

Podpisywanie aplikacji umożliwia deweloperom identyfikowanie autora aplikacji i jej aktualizowanie bez tworzenia skomplikowanych interfejsów i uprawnień. Każda aplikacja działająca na platformie Android 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 umożliwia nawiązanie zaufania między Google a deweloperem oraz między deweloperem a aplikacją. Deweloperzy wiedzą, że ich aplikacja jest dostarczana w niezmodyfikowanej formie na urządzenie z Androidem, i mogą zostać pociągnięci do odpowiedzialności za jej działanie.

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 którą aplikacją. Różne aplikacje działają pod różnymi identyfikatorami użytkownika. Podpisywanie aplikacji zapewnia, że jedna aplikacja nie może uzyskać dostępu do żadnej innej aplikacji inaczej niż za pomocą dobrze zdefiniowanego interfejsu IPC.

Gdy aplikacja (plik APK) zostanie zainstalowana na urządzeniu z Androidem, menedżer pakietów sprawdzi, czy plik APK został prawidłowo podpisany certyfikatem zawartym w tym pliku. Jeśli certyfikat (a ściślej mówią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 firmę zewnętrzną (OEM, operatora, alternatywny rynek) lub przez siebie. Android umożliwia podpisywanie kodu za pomocą samodzielnie podpisanych certyfikatów, które deweloperzy mogą generować bez pomocy zewnętrznej lub zgody. Aplikacje nie muszą być podpisane przez urząd centralny. Android obecnie nie weryfikuje certyfikatów aplikacji pod kątem 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 współdzielonego 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:

Aby zapewnić maksymalną zgodność, podpisuj aplikacje we wszystkich schematach, najpierw w wersji 1, potem w wersji 2, a na końcu w wersji 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 plików JAR (schemat 1)

Podpisywanie plików APK jest częścią Androida od samego początku. Jest ono oparte na podpisanym pliku JAR. Szczegółowe informacje o używaniu tego schematu znajdziesz w dokumentacji Androida Studio na temat podpisywania aplikacji.

Podpisy w wersji 1 nie chronią niektórych części pliku APK, takich jak metadane ZIP. Sprawdzacz APK musi przetworzyć wiele niesprawdzonych (jeszcze niezweryfikowanych) struktur danych, a potem odrzucić dane, które nie są objęte podpisami. 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 lub nowszym obsługują schemat podpisywania plików APK w wersji 2 (schemat 2) i nowszej. (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 o stosowaniu schematu w wersji 2+ w aplikacji znajdziesz w artykule Schemat podpisu plików 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.

Proces weryfikacji podpisu pliku APK

Rysunek 1. Proces weryfikacji podpisu pliku APK

Cały plik APK jest weryfikowany pod kątem podpisu w wersji 2+ zapisanego 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 pliku APK unieważniają podpis pliku APK w wersji 2+. 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.