apksigner

Narzędzie apksigner, dostępne w Narzędziach Android SDK Build Tools w wersji 24.0.3 lub nowszej, pozwala podpisywać pliki APK i potwierdzać, czy podpis pliku APK zostanie zweryfikowany we wszystkich wersjach platformy Androida obsługiwanych przez ten plik APK.

Ta strona zawiera krótki przewodnik na temat korzystania z narzędzia oraz informacje o różnych opcjach wiersza poleceń obsługiwanych przez to narzędzie. Pełny opis sposobu używania narzędzia apksigner do podpisywania plików APK znajdziesz w artykule Podpisywanie aplikacji.

Uwaga: jeśli podpiszesz pakiet APK za pomocą apksigner i wprowadzisz w nim dalsze zmiany, podpis pliku APK zostanie unieważniony. Jeśli do dostosowania pliku APK używasz zipalign, użyj go przed podpisaniem pliku APK.

Wykorzystanie

Podpisywanie pakietu APK

Składnia podpisywania pakietu APK za pomocą narzędzia apksigner jest taka:

apksigner sign --ks keystore.jks |
  --key key.pk8 --cert cert.x509.pem
  [signer_options] app-name.apk

Gdy podpisujesz plik APK za pomocą narzędzia apksigner, musisz podać klucz prywatny i certyfikat osoby podpisującej. Możesz dołączyć te informacje na 2 sposoby:

  • Określ plik KeyStore za pomocą opcji --ks.
  • Określ oddzielnie plik klucza prywatnego i plik certyfikatu, używając odpowiednio opcji --key i --cert. Plik klucza prywatnego musi mieć format PKCS8, a plik certyfikatu musi mieć format X.509.

Zwykle plik APK jest podpisywany tylko przez jedną osobę podpisującą. Jeśli musisz podpisać plik APK przy użyciu wielu sygnatariuszy, użyj opcji --next-signer, aby oddzielić zestaw ogólnych opcji, które będą stosowane do poszczególnych sygnatariuszy:

apksigner sign [signer_1_options] --next-signer [signer_2_options] app-name.apk

Sprawdzanie podpisu pliku APK

Składnia potwierdzająca pomyślną weryfikację podpisu pakietu APK na obsługiwanych platformach jest taka:

apksigner verify [options] app-name.apk

Wykonaj rotację kluczy podpisywania

Składnia rotacji historii certyfikatu podpisywania lub nowej sekwencji podpisów jest taka:

$ apksigner rotate --in /path/to/existing/lineage \
  --out /path/to/new/file \
  --old-signer --ks old-signer-jks \
  --new-signer --ks new-signer-jks

Opcje

Poniżej znajdziesz zestaw opcji każdego polecenia obsługiwanego przez narzędzie apksigner.

Podpisz polecenie

Polecenie podpisu apksigner zawiera następujące opcje.

Opcje ogólne

Te opcje określają podstawowe ustawienia, które należy zastosować do osoby podpisującej:

--out <apk-filename>
Lokalizacja, w której chcesz zapisać podpisany plik APK. Jeśli ta opcja nie zostanie podana wprost, pakiet APK zostanie podpisany, co spowoduje zastąpienie wejściowego pliku APK.
--min-sdk-version <integer>
Najniższy poziom interfejsu API platformy Androida, którego apksigner używa do potwierdzania podpisu pliku APK. Wyższe wartości pozwalają narzędziu na użycie silniejszych parametrów zabezpieczeń podczas podpisywania aplikacji, ale ogranicza dostępność pliku APK do urządzeń z najnowszymi wersjami Androida. Domyślnie apksigner używa wartości atrybutu minSdkVersion z pliku manifestu aplikacji.
--max-sdk-version <integer>
Najwyższy poziom interfejsu API platformy Androida, którego apksigner używa do potwierdzania podpisu pliku APK. Domyślnie narzędzie używa najwyższego możliwego poziomu interfejsu API.
--rotation-min-sdk-version <integer>
Najniższy poziom interfejsu API, z którego powinien korzystać poddany rotacji klucz podpisywania APK do wygenerowania podpisu pakietu APK. We wszystkich poprzednich wersjach platformy będzie używany oryginalny (bez rotacji) klucz podpisywania pliku APK. Domyślnie rotowane klucze podpisywania, które są obsługiwane na urządzeniach z Androidem 13 (poziom interfejsu API 33) lub nowszym, są używane z blokiem podpisywania w wersji 3.1.

Uwaga: jeśli Twoja aplikacja została podpisana rotowanym kluczem podpisywania na urządzeniu z Androidem 12L (poziom interfejsu API 32) lub niższym, musisz użyć --rotation-min-sdk-version 28, aby nadal podpisywać aplikację za pomocą rotacji klucza podpisywania dla Androida 9 (poziom interfejsu API 28).

--v1-signing-enabled <true | false>
Określa, czy apksigner podpisuje dany pakiet APK za pomocą tradycyjnego schematu podpisywania opartego na JAR. Domyślnie narzędzie używa wartości --min-sdk-version i --max-sdk-version, aby zdecydować, kiedy zastosować ten schemat podpisu.
--v2-signing-enabled <true | false>
Określa, czy apksigner podpisuje dany pakiet APK za pomocą schematu podpisu pliku APK w wersji 2. Domyślnie narzędzie używa wartości --min-sdk-version i --max-sdk-version, aby zdecydować, kiedy zastosować ten schemat podpisu.
--v3-signing-enabled <true | false>
Określa, czy apksigner podpisuje dany pakiet APK za pomocą schematu podpisu pliku APK w wersji 3. Domyślnie narzędzie używa wartości --min-sdk-version i --max-sdk-version, aby zdecydować, kiedy zastosować ten schemat podpisu.
--v4-signing-enabled <true | false | only>

Określa, czy apksigner podpisuje dany pakiet APK za pomocą schematu podpisu pliku APK w wersji 4. Ten schemat tworzy podpis w osobnym pliku (apk-name.apk.idsig). Jeśli true i plik APK nie są podpisane, podpis w wersji 2 lub 3 jest generowany na podstawie wartości --min-sdk-version i --max-sdk-version. Następnie polecenie tworzy plik .idsig na podstawie treści podpisanego pakietu APK.

Użyj only, aby wygenerować tylko podpis w wersji 4 bez modyfikowania pliku APK i podpisów, które miał przed wywołaniem. only kończy się niepowodzeniem, jeśli plik APK nie ma jeszcze podpisu w wersji 2 lub 3 albo podpis używa innego klucza niż ten podany do bieżącego wywołania.

Domyślnie narzędzie używa wartości --min-sdk-version i --max-sdk-version, aby zdecydować, kiedy zastosować ten schemat podpisu.

-v, --verbose
Użyj trybu szczegółowych danych wyjściowych.

Opcje dla podpisujących

Poniższe opcje określają konfigurację konkretnej osoby podpisującej. Te opcje nie są konieczne, jeśli podpisujesz aplikację tylko za pomocą jednego sygnatariusza.

--next-signer <signer-options>
Używane do określania różnych ogólnych opcji dla każdego sygnatariusza.
--v1-signer-name <basename>
Podstawowa nazwa plików składających się na podpis oparty na JAR dla bieżącego podpisującego. Domyślnie apksigner używa aliasu klucza magazynu kluczy lub nazwy bazowej pliku klucza dla tego podpisującego.

Opcje klucza i certyfikatu

Te opcje określają klucz prywatny i certyfikat osoby podpisującej:

--ks <filename>
Klucz prywatny i łańcuch certyfikatów osoby podpisującej znajdują się w danym pliku KeyStore opartym na Javie. Jeśli nazwa pliku jest ustawiona na "NONE", magazyn kluczy zawierający klucz i certyfikat nie wymaga określonego pliku. Dotyczy to niektórych magazynów kluczy PKCS #11.
--ks-key-alias <alias>
Nazwa aliasu reprezentującego klucz prywatny osoby podpisującej i dane certyfikatu w magazynie kluczy. Jeśli magazyn kluczy powiązany z osobą podpisującą zawiera wiele kluczy, musisz określić tę opcję.
--ks-pass <input-format>

Hasło do magazynu kluczy, który zawiera klucz prywatny i certyfikat osoby podpisującej. Aby otworzyć magazyn kluczy, musisz podać hasło. Narzędzie apksigner obsługuje te formaty:

  • pass:<password> – hasło podane w tekście w pozostałej części polecenia apksigner sign.
  • env:<name> – hasło jest przechowywane w podanej zmiennej środowiskowej.
  • file:<filename> – hasło jest przechowywane w pojedynczym wierszu w pliku.
  • stdin – hasło jest podawane w postaci pojedynczego wiersza w standardowym strumieniu danych wejściowych. Jest to domyślne zachowanie --ks-pass.

Uwaga: jeśli w tym samym pliku umieścisz kilka haseł, podaj je w oddzielnych wierszach. Narzędzie apksigner łączy hasła z sygnatariuszami pakietu APK na podstawie ich kolejności, w jakiej je sygnatujesz. Jeśli dla osoby podpisującej podasz 2 hasła, apksigner zinterpretuje pierwsze hasło jako hasło magazynu kluczy, a drugie jako hasło klucza.

--pass-encoding <charset>
Uwzględnia określone kodowanie znaków, takie jak ibm437 lub utf-8, przy próbie obsługi haseł zawierających znaki spoza zestawu ASCII.

Keytool często szyfruje magazyny kluczy, konwertując hasło za pomocą domyślnego zestawu znaków konsoli. Domyślnie apksigner próbuje odszyfrować dane przy użyciu kilku form hasła:

  • Formularz Unicode
  • Formularz zakodowany z użyciem domyślnego zestawu znaków JVM
  • W Javie 8 i starszych formularz zakodowany z użyciem domyślnego zestawu znaków konsoli
  • W środowisku Java 9 apksigner nie może wykryć zestawu znaków konsoli. Jeśli używane jest hasło spoza zestawu ASCII, może być konieczne podanie --pass-encoding. Może być też konieczne określenie tej opcji w magazynach kluczy, które narzędzie Keytool utworzyło w innym systemie operacyjnym lub w innym języku.

    --key-pass <input-format>

    Hasło klucza prywatnego osoby podpisującej, które jest potrzebne, jeśli klucz prywatny jest chroniony hasłem. Narzędzie apksigner obsługuje te formaty:

    • pass:<password> – hasło jest podawane w tekście w pozostałej części polecenia apksigner sign.
    • env:<name> – hasło jest przechowywane w podanej zmiennej środowiskowej.
    • file:<filename> – hasło jest przechowywane w pojedynczym wierszu w pliku.
    • stdin – hasło jest podawane w postaci pojedynczego wiersza w standardowym strumieniu danych wejściowych. Jest to domyślne zachowanie --key-pass.
    --ks-type <algorithm>
    Typ lub algorytm powiązany z magazynem kluczy zawierającym klucz prywatny i certyfikat osoby podpisującej. Domyślnie apksigner używa typu zdefiniowanego jako stała keystore.type w pliku właściwości zabezpieczeń.
    --ks-provider-name <name>
    Nazwa dostawcy JCA używanego w przypadku żądania implementacji magazynu kluczy osoby podpisującej. Domyślnie apksigner używa dostawcy o najwyższym priorytecie.
    --ks-provider-class <class-name>
    Pełna i jednoznaczna nazwa klasy dostawcy JCA używana w przypadku żądania implementacji magazynu kluczy osoby podpisującej. Ta opcja jest alternatywą dla --ks-provider-name. Domyślnie apksigner używa dostawcy określonego za pomocą opcji --ks-provider-name.
    --ks-provider-arg <value>
    Wartość ciągu znaków, który ma być przekazywany jako argument dla konstruktora klasy dostawcy JCA. Sama klasa jest definiowana za pomocą opcji --ks-provider-class. Domyślnie apksigner używa konstruktora klasy bez argumentów.
    --key <filename>
    Nazwa pliku zawierającego klucz prywatny osoby podpisującej. Ten plik musi mieć format PKCS #8 DER. Jeśli klucz jest chroniony hasłem, apksigner prosi o podanie hasła przy użyciu standardowego sposobu wprowadzania tekstu, chyba że określisz inny format wprowadzania za pomocą opcji --key-pass.
    --cert <filename>
    Nazwa pliku zawierającego łańcuch certyfikatów osoby podpisującej. Ten plik musi być w formacie X.509 PEM lub DER.

    Zweryfikuj polecenie

    Polecenie weryfikacji apksigner zawiera te opcje.

    --print-certs
    Pokaż informacje o certyfikatach podpisywania pakietu APK.
    --min-sdk-version <integer>
    Najniższy poziom interfejsu API platformy Androida, którego apksigner używa do potwierdzania podpisu pliku APK. Wyższe wartości pozwalają narzędziu na użycie silniejszych parametrów zabezpieczeń podczas podpisywania aplikacji, ale ogranicza dostępność pliku APK do urządzeń z najnowszymi wersjami Androida. Domyślnie apksigner używa wartości atrybutu minSdkVersion z pliku manifestu aplikacji.
    --max-sdk-version <integer>
    Najwyższy poziom interfejsu API platformy Androida, którego apksigner używa do potwierdzania podpisu pliku APK. Domyślnie narzędzie używa najwyższego możliwego poziomu interfejsu API.
    -v, --verbose
    Użyj trybu szczegółowych danych wyjściowych.
    -Werr
    Traktuj ostrzeżenia jako błędy.

    Przykłady

    Poniżej podano przykłady z użyciem funkcji apksigner.

    Podpisywanie pakietu APK

    Podpisz plik APK przy użyciu release.jks, który jest jedynym kluczem w KeyStore:

    $ apksigner sign --ks release.jks app.apk
    

    Podpisz plik APK za pomocą klucza prywatnego i certyfikatu przechowywanych w osobnych plikach:

    $ apksigner sign --key release.pk8 --cert release.x509.pem app.apk
    

    Podpisz plik APK, używając 2 kluczy:

    $ apksigner sign --ks first-release-key.jks --next-signer --ks second-release-key.jks app.apk
    

    Podpisz plik APK z wykorzystaniem rotacji klucza podpisywania i pakietu SDK w wersji 28 lub nowszej kierowanego na rotację:

    $ apksigner sign --ks release.jks --next-signer --ks release2.jks \
      --lineage /path/to/signing/history/lineage app.apk \
      --rotation-min-sdk-version 28
    

    Podpisz plik APK, używając rotacji klucza podpisywania i pakietu SDK w wersji 33 lub nowszej kierowanego na rotację:

    $ apksigner sign --ks release.jks --next-signer --ks release2.jks \
      --lineage /path/to/signing/history/lineage app.apk
    

    Sprawdzanie podpisu pliku APK

    Sprawdź, czy podpisy w pliku APK powinny zostać potwierdzone jako prawidłowe na wszystkich platformach Androida, które obsługuje ten plik:

    $ apksigner verify app.apk
    

    Sprawdź, czy podpisy pliku APK powinny zostać potwierdzone na Androidzie 4.0.3 (poziom interfejsu API 15) i nowszych:

    $ apksigner verify --min-sdk-version 15 app.apk
    

    Wykonaj rotację kluczy podpisywania

    Włącz historię danych certyfikatu podpisywania, która obsługuje rotację klucza:

    $ apksigner rotate --out /path/to/new/file --old-signer \
        --ks release.jks --new-signer --ks release2.jks

    Ponownie wykonaj rotację kluczy podpisywania:

    $ apksigner rotate --in /path/to/existing/lineage \
      --out /path/to/new/file --old-signer --ks release2.jks \
      --new-signer --ks release3.jks