apksigner

您可以使用 Android SDK Build Tools 24.0.3 以上修訂版本提供的 apksigner 工具簽署 APK,並確認 APK 簽名能在 APK 支援的所有 Android 平台版本成功通過驗證。

本頁面提供這項工具的簡短使用指南,並以及此工具支援的其他指令列選項參考資料。如需關於使用 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 時,您必須提供簽署者的私密金鑰和憑證。您可透過下列兩種方式加入這類資訊:

  • 使用 --ks 選項指定 KeyStore 檔案。
  • 使用 --key--cert 選項分別指定私密金鑰檔案和憑證檔案。私密金鑰檔案必須使用 PKCS #8 格式,而憑證檔案必須使用 X.509 格式。

一般來說,您只需使用一個簽署者簽署 APK。如果您需要使用多個簽署者簽署 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>
apksigner 用於確認 APK 簽名能通過驗證的最低 Android 架構 API 級別。較大的值可讓工具在簽署應用程式時使用更強的安全性參數,但會限制 APK 只能在搭載較新版 Android 的裝置上使用。 根據預設,apksigner 會使用應用程式資訊清單檔案中的 minSdkVersion 屬性值。
--max-sdk-version <integer>
apksigner 用於確認 APK 簽名能通過驗證的最高 Android 架構 API 級別。根據預設,這項工具會使用可用的最高 API 級別。
--rotation-min-sdk-version <integer>
最低 API 級別的 APK 輪替簽署金鑰應該用於產生 APK 簽名。APK 的原始 (非輪替) 簽署金鑰將會用於所有舊平台版本。根據預設,搭載 Android 13 (API 級別 33) 以上版本的裝置都支援輪替簽署金鑰,這類金鑰會與 v3.1 簽署區塊搭配使用。

注意:如果應用程式曾在搭載 Android 12L (API 級別 32) 以下版本的裝置上透過輪替簽署金鑰簽署,則必須使用 --rotation-min-sdk-version 28 搭配 Android 9 (API 級別 28) 的輪替簽署金鑰繼續簽署應用程式。

--v1-signing-enabled <true | false>
判斷 apksigner 是否使用傳統的 JAR 簽署配置來簽署指定的 APK 套件。根據預設,工具會使用 --min-sdk-version--max-sdk-version 的值來判斷何時應套用這項簽署配置。
--v2-signing-enabled <true | false>
判斷 apksigner 是否使用 APK 簽署配置 v2 簽署指定的 APK 套件。根據預設,工具會根據 --min-sdk-version--max-sdk-version 的值判斷何時應套用這項簽署配置。
--v3-signing-enabled <true | false>
判斷 apksigner 是否使用 APK 簽署配置 v3 簽署指定的 APK 套件。根據預設,工具會根據 --min-sdk-version--max-sdk-version 的值判斷何時應套用這項簽署配置。
--v4-signing-enabled <true | false | only>

判斷 apksigner 是否使用 APK 簽署配置 v4 簽署指定的 APK 套件。這項配置會在另一個檔案 (apk-name.apk.idsig) 中產生簽名。如果為 true 且 APK 未簽署,則系統會依據 --min-sdk-version--max-sdk-version 的值產生 v2 或 v3 簽名。這項指令接著會根據已簽署的 APK 內容產生 .idsig 檔案。

使用 only 只會產生 v4 簽名,而不會修改 APK 以及叫用前已有的任何簽名。如果 APK 沒有 v2 或 v3 簽名,或者簽名使用的金鑰與提供給目前叫用的金鑰不同,only 就會失敗。

根據預設,工具會根據 --min-sdk-version--max-sdk-version 的值判斷何時應套用這項簽署配置。

-v--verbose
使用詳細輸出模式。

各簽署者選項

下列選項會指定特定簽署者的設定。如果您僅使用一個簽署者簽署應用程式,則這些為非必要選項。

--next-signer <signer-options>
用於為每個簽署者指定不同的一般選項。
--v1-signer-name <basename>
檔案的基本名稱,構成目前簽署者的 JAR 簽名。對於該簽署者,apksigner 預設會使用 KeyStore 的金鑰別名或金鑰檔案基本名稱。

金鑰和憑證選項

下列選項會指定簽署者的私密金鑰和憑證:

--ks <filename>
簽署者的私密金鑰和憑證鏈結會存放在指定的 Java KeyStore 檔案中。如果檔案名稱設為 "NONE",則包含金鑰和憑證的 KeyStore 不需要指定檔案,某些 PKCS #11 KeyStore 就是如此。
--ks-key-alias <alias>
代表 KeyStore 中簽署者私密金鑰和憑證資料的別名名稱。如果與簽署者相關聯的 KeyStore 含有多個金鑰,您就必須指定這個選項。
--ks-pass <input-format>

含有簽署者私密金鑰和憑證的 KeyStore 密碼。您必須提供密碼才能開啟 KeyStore。apksigner 工具支援下列格式:

  • pass:<password>:提供的密碼內嵌於其他 apksigner sign 指令。
  • env:<name>:密碼會儲存在指定的環境變數中。
  • file:<filename>:密碼會以單行儲存在指定的檔案中。
  • stdin:提供的密碼以單行顯示在標準輸入串中。這是 --ks-pass 的預設行為。

注意:如果一個檔案包含多個密碼,請分行列出。apksigner 工具會根據您指定簽署者的順序,將密碼與 APK 簽署者建立關聯。如果您為簽署者提供兩個密碼,apksigner 會將第一個密碼解讀為 KeyStore 密碼,並將第二個密碼解讀為金鑰密碼。

--pass-encoding <charset>
在嘗試處理含有非 ASCII 字元的密碼時,納入指定的字元編碼 (例如 ibm437utf-8)。

一般來說,Keytool 會使用控制台的預設字元集轉換密碼,藉此加密 KeyStore。根據預設,apksigner 會使用多種密碼格式嘗試解密:

  • 萬國碼 (Unicode) 格式
  • 使用 JVM 預設字元集的編碼格式
  • 在 Java 8 以下版本中,使用控制台預設字元集的編碼格式
  • 在 Java 9 中,apksigner 無法偵測控制台的字元集。 因此,如果您使用非 ASCII 密碼,就可能需要指定 --pass-encoding。您可能也需要針對 Keytool 在其他 OS 或以不同語言代碼建立的 KeyStore 指定這個選項。

    --key-pass <input-format>

    簽署者的私密金鑰密碼 (如果私密金鑰受到密碼保護,就需要使用)。apksigner 工具支援下列格式:

    • pass:<password>:提供的密碼內嵌於其他 apksigner sign 指令。
    • env:<name>:密碼會儲存在指定的環境變數中。
    • file:<filename>:密碼會以單行儲存在指定的檔案中。
    • stdin:提供的密碼以單行顯示在標準輸入串中。這是 --key-pass 的預設行為。
    --ks-type <algorithm>
    與包含簽署者私密金鑰和憑證的 KeyStore 相關聯的類型或演算法。根據預設,apksigner 會使用在安全性屬性檔案中定義為 keystore.type 常數的類型。
    --ks-provider-name <name>
    要求簽署者 KeyStore 實作時使用的 JCA Provider 名稱。根據預設,apksigner 會使用優先順序最高的提供者。
    --ks-provider-class <class-name>
    要求簽署者 KeyStore 實作時使用的 JCA Provider 完整類別名稱。這個選項可以做為 --ks-provider-name 的替代選項。根據預設,apksigner 會使用 --ks-provider-name 選項指定的提供者。
    --ks-provider-arg <value>
    傳遞做為 JCA Provider 類別建構函式引數的字串值。類別本身是透過 --ks-provider-class 選項定義。根據預設,apksigner 會使用類別的無引數建構函式。
    --key <filename>
    包含簽署者私密金鑰的檔案名稱。這個檔案必須採用 PKCS #8 DER 格式。如果金鑰受到密碼保護,除非您使用 --key-pass 選項指定不同輸入格式,否則 apksigner 會提示您使用標準輸入格式輸入密碼。
    --cert <filename>
    包含簽署者憑證鏈結的檔案名稱。這個檔案必須使用 X.509 PEM 或 DER 格式。

    驗證指令

    apksigner 驗證指令包含下列選項。

    --print-certs
    顯示 APK 簽署憑證的相關資訊。
    --min-sdk-version <integer>
    apksigner 用於確認 APK 簽名能通過驗證的最低 Android 架構 API 級別。較大的值可讓工具在簽署應用程式時使用更強的安全性參數,但會限制 APK 只能在搭載較新版 Android 的裝置上使用。 根據預設,apksigner 會使用應用程式資訊清單檔案中的 minSdkVersion 屬性值。
    --max-sdk-version <integer>
    apksigner 用於確認 APK 簽名能通過驗證的最高 Android 架構 API 級別。根據預設,這項工具會使用可用的最高 API 級別。
    -v--verbose
    使用詳細輸出模式。
    -Werr
    將警告視為錯誤。

    範例

    以下是 apksigner 的使用範例。

    簽署 APK

    使用 KeyStore 中唯一的金鑰 release.jks 簽署 APK:

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

    使用儲存為個別檔案的私密金鑰和憑證簽署 APK:

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

    使用兩個金鑰簽署 APK:

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

    使用輪替簽署金鑰簽署 APK,且該輪替指定 SDK 28 以上版本:

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

    使用輪替簽署金鑰簽署 APK,且該輪替指定 SDK 33 以上版本:

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

    驗證 APK 的簽名

    檢查 APK 簽名是否會在 APK 支援的所有 Android 平台上確認為有效:

    $ apksigner verify app.apk
    

    檢查 APK 簽名是否會在 Android 4.0.3 (API 級別 15) 以上版本中確認為有效:

    $ 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