apksigner

apksigner ツール(Android SDK Build Tools 24.0.3 以降で使用可能)を使用すると、APK に署名し、その APK がサポートする Android プラットフォームのすべてのバージョンで APK の署名が正常に検証されることを確認できます。

このページは、このツールの使用方法に関する簡単なガイドであり、このツールがサポートするさまざまなコマンドライン オプションのリファレンスとして使用できます。apksigner ツールを使用して APK に署名する方法の詳細な説明については、アプリへの署名をご覧ください。

注意: apksigner を使用して APK に署名した後で APK にさらに変更を加えると、APK の署名は無効になります。zipalign を使用して APK のアライメントを調整する場合は、APK に署名する前に使用してください。

使用方法

APK に署名する

apksigner ツールを使用して APK に署名するための構文は次のとおりです。

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

apksigner ツールを使用して APK に署名する際は、署名者の秘密鍵と証明書を指定する必要があります。この情報を指定する方法は 2 つあります。

  • --ks オプションを使用してキーストア ファイルを指定します。
  • --key オプションと --cert オプションを使用して、それぞれ秘密鍵ファイルと証明書ファイルを別個に指定します。秘密鍵ファイルには PKCS #8 形式を使用し、証明書ファイルには X.509 形式を使用する必要があります。

通常は、1 つの APK の署名に使用する署名者は 1 人です。複数の署名者を使用して APK に署名する必要がある場合は、--next-signer オプションを使用して、各署名者に適用する全般オプションのセットを個別に指定します。

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

APK の署名を検証する

サポートしているプラットフォーム上で APK の署名が正常に検証されているどうかを確かめるには、次の構文を使用します。

apksigner verify [options] app-name.apk

署名鍵をローテーションする

署名証明書の系列、つまり署名の新しいシーケンスをローテーションするには、次の構文を使用します。

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

オプション

以下では、apksigner ツールがサポートするコマンドごとに、オプションのセットを一覧表示します。

署名コマンド

apksigner 署名コマンドには、次のオプションがあります。

全般オプション

以下のオプションでは、署名者に適用する基本設定を指定します。

--out <apk-filename>
署名した APK を保存する場所。このオプションを明示的に指定しない場合、APK パッケージはその場で署名され、入力 APK ファイルが上書きされます。
--min-sdk-version <integer>
APK の署名が検証されることを確認するために apksigner が使用する Android Framework の最小 API レベル。値が大きいほど、ツールでのアプリの署名に使用できるセキュリティ パラメータの強度が高くなりますが、APK を利用できるデバイスは Android のバージョンが新しいものに限定されます。デフォルトでは、apksigner はアプリのマニフェスト ファイルの minSdkVersion 属性の値を使用します。
--max-sdk-version <integer>
APK の署名が検証されることを確認するために apksigner が使用する Android Framework の最大 API レベル。デフォルトでは、ツールは使用可能な最大の API レベルを使用します。
--rotation-min-sdk-version <integer>
APK の署名を生成するために APK のローテーションされた署名鍵が使用する最小 API レベル。APK の元の(ローテーションされていない)署名鍵は、以前のすべてのプラットフォーム バージョンで使用されます。デフォルトでは、ローテーションされた署名鍵は v3.1 署名ブロックとともに使用されます。この署名鍵は、Android 13(API レベル 33)以降を搭載しているデバイスでサポートされています。

注: Android 12L(API レベル 32)以下を搭載しているデバイスで、ローテーションされた署名鍵によってアプリが署名されている場合は、--rotation-min-sdk-version 28 を使用して、Android 9(API レベル 28)用のローテーションされた署名鍵でアプリの署名を継続してください。

--v1-signing-enabled <true | false>
指定された APK パッケージに apksigner が署名する際に、従来の JAR ベースの署名スキームを使用するかどうかを指定します。デフォルトでは、このツールは --min-sdk-version--max-sdk-version の値を使用して、この署名スキームをいつ適用するかを決定します。
--v2-signing-enabled <true | false>
指定された APK パッケージに apksigner が署名する際に、APK 署名スキーム v2 を使用するかどうかを指定します。デフォルトでは、このツールは --min-sdk-version--max-sdk-version の値を使用して、この署名スキームをいつ適用するかを決定します。
--v3-signing-enabled <true | false>
指定された APK パッケージに apksigner が署名する際に、APK 署名スキーム v3 を使用するかどうかを指定します。デフォルトでは、このツールは --min-sdk-version--max-sdk-version の値を使用して、この署名スキームをいつ適用するかを決定します。
--v4-signing-enabled <true | false | only>

指定された APK パッケージに apksigner が署名する際に、APK 署名スキーム v4 を使用するかどうかを指定します。このスキームでは、別のファイル(apk-name.apk.idsig)に署名が生成されます。true を指定した場合、APK が署名されていないと、--min-sdk-version--max-sdk-version の値に基づいて v2 または v3 署名が生成されます。さらにこのコマンドでは、署名済みの APK の内容に基づいて .idsig ファイルが生成されます。

APK と呼び出し前の APK の署名を変更せずに v4 署名のみを生成するには、only を使用します。APK に v2 または v3 署名がまだない場合、または、現在の呼び出しで指定されたものとは異なる鍵が使用されている署名の場合、only を指定すると失敗します。

デフォルトでは、このツールは --min-sdk-version--max-sdk-version の値を使用して、この署名スキームをいつ適用するかを決定します。

-v--verbose
詳細出力モードを使用します。

署名者ごとのオプション

以下のオプションでは、特定の署名者の構成を指定します。1 人の署名者だけを使用してアプリに署名する場合、これらのオプションは必要ありません。

--next-signer <signer-options>
署名者ごとに異なる全般オプションを指定するために使用します。
--v1-signer-name <basename>
現在の署名者の JAR ベース署名を構成するファイルのベース名。デフォルトでは、apksigner は、キーストアの鍵エイリアスか、この署名者の鍵ファイルのベース名を使用します。

鍵と証明書のオプション

以下のオプションでは、署名者の秘密鍵と証明書を指定します。

--ks <filename>
署名者の秘密鍵と証明書チェーンは、指定された Java ベースのキーストア ファイル内に存在します。ファイル名を "NONE" に設定した場合、鍵と証明書を含むキーストアにファイルを指定する必要はありません。これは一部の PKCS #11 キーストアのケースに該当します。
--ks-key-alias <alias>
キーストア内にある署名者の秘密鍵と証明書のデータを示すエイリアスの名前。署名者に関連付けられているキーストアに複数の鍵が含まれている場合、このオプションを指定する必要があります。
--ks-pass <input-format>

署名者の秘密鍵と証明書が含まれているキーストアのパスワード。キーストアを開くためのパスワードを指定する必要があります。apksigner ツールでは、以下の形式がサポートされています。

  • pass:<password>apksigner sign コマンドの他の部分と一緒にインラインでパスワードを指定します。
  • env:<name> – パスワードは、指定された環境変数に格納されています。
  • file:<filename> – パスワードは、指定されたファイルに単一行として格納されています。
  • stdin – パスワードは、標準入力ストリームに単一行で指定されます。これは、--ks-pass のデフォルトの動作です。

注: 同じファイルに複数のパスワードを含める場合は、別々の行に指定します。apksigner ツールは、署名者を指定した順序に基づいて、パスワードを APK の署名者に関連付けます。1 人の署名者に 2 つのパスワードを指定した場合、apksigner は、1 つ目をキーストアのパスワードと解釈し、2 つ目を鍵のパスワードと解釈します。

--pass-encoding <charset>
非 ASCII 文字を含むパスワードを処理する際の文字エンコード(ibm437utf-8 など)を指定します。

keytool は多くの場合、キーストアを暗号化するために、コンソールのデフォルト文字セットを使用してパスワードの変換を行います。デフォルトでは、apksigner は以下の複数のパスワード形式を使用して復号を試みます。

  • Unicode 形式
  • JVM のデフォルト文字セットを使用してエンコードされた形式
  • Java 8 以前でコンソールのデフォルト文字セットを使用してエンコードされた形式
  • Java 9 では、apksigner はコンソールの文字セットを検出できません。非 ASCII パスワードを使用する場合は、--pass-encoding の指定が必要になることがあります。また、異なる OS 上または異なるロケールで keytool が作成したキーストアの場合も、このオプションの指定が必要になることがあります。

    --key-pass <input-format>

    署名者の秘密鍵のパスワード。これは、秘密鍵がパスワードで保護されている場合に必要です。apksigner ツールでは、以下の形式がサポートされています。

    • pass:<password>apksigner sign コマンドの他の部分と一緒にインラインでパスワードを指定します。
    • env:<name> – パスワードは、指定された環境変数に格納されています。
    • file:<filename> – パスワードは、指定されたファイルに単一行として格納されています。
    • stdin – パスワードは、標準入力ストリームに単一行で指定されます。これは、--key-pass のデフォルトの動作です。
    --ks-type <algorithm>
    署名者の秘密鍵と証明書が含まれているキーストアに関連付けられたタイプまたはアルゴリズム。デフォルトでは、apksigner は、セキュリティ プロパティ ファイル内の keystore.type 定数として定義されているタイプを使用します。
    --ks-provider-name <name>
    署名者のキーストア実装をリクエストする際に使用する JCA プロバイダの名前。デフォルトでは、apksigner は優先度が最も高いプロバイダを使用します。
    --ks-provider-class <class-name>
    署名者のキーストア実装をリクエストする際に使用する JCA プロバイダの完全修飾クラス名。このオプションは、--ks-provider-name の代わりになります。デフォルトでは、apksigner は、--ks-provider-name オプションで指定されたプロバイダを使用します。
    --ks-provider-arg <value>
    JCA プロバイダ クラスのコンストラクタの引数として渡す文字列値。クラスそのものは --ks-provider-class オプションで定義されます。デフォルトでは、apksigner は、そのクラスの引数なしのコンストラクタを使用します。
    --key <filename>
    署名者の秘密鍵が含まれているファイルの名前。このファイルには、PKCS #8 DER 形式を使用する必要があります。鍵がパスワードで保護されている場合、--key-pass オプションで別の種類の入力形式が指定されていなければ、apksigner は標準入力によるパスワードの指定を要求します。
    --cert <filename>
    署名者の証明書チェーンが含まれているファイルの名前。このファイルには、X.509 PEM 形式または X.509 DER 形式を使用する必要があります。

    検証コマンド

    apksigner 検証コマンドには次のオプションがあります。

    --print-certs
    APK の署名証明書に関する情報を表示します。
    --min-sdk-version <integer>
    APK の署名が検証されることを確認するために apksigner が使用する Android Framework の最小 API レベル。値が大きいほど、ツールでのアプリの署名に使用できるセキュリティ パラメータの強度が高くなりますが、APK を利用できるデバイスは Android のバージョンが新しいものに限定されます。デフォルトでは、apksigner はアプリのマニフェスト ファイルの minSdkVersion 属性の値を使用します。
    --max-sdk-version <integer>
    APK の署名が検証されることを確認するために apksigner が使用する Android Framework の最大 API レベル。デフォルトでは、ツールは使用可能な最大の API レベルを使用します。
    -v--verbose
    詳細出力モードを使用します。
    -Werr
    警告をエラーとして扱います。

    apksigner を使用した例を次に示します。

    APK に署名する

    キーストア内の唯一の鍵である release.jks を使用して、APK に署名します。

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

    別々のファイルに保存されている秘密鍵と証明書を使って、APK に署名します。

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

    2 つの鍵を使って、APK に署名します。

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

    ローテーションされた署名鍵と、SDK バージョン 28 以降を対象とするローテーションで、APK に署名します。

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

    ローテーションされた署名鍵と、SDK バージョン 33 以降を対象とするローテーションで、APK に署名します。

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

    APK の署名を検証する

    APK がサポートするすべての Android プラットフォームで、APK の署名の有効性が検証されると想定できるかどうかをチェックします。

    $ apksigner verify app.apk
    

    Android 4.0.3(API レベル 15)以上で APK の署名の有効性が検証されると想定できるかどうかをチェックします。

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

    署名鍵をローテーションする

    鍵のローテーションをサポートする署名証明書の系列を有効にします。

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

    署名鍵を再度ローテーションします。

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