您可以使用 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 簽署區塊搭配使用。
--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 在叫用前具有的任何簽名。如果 APK 沒有 v2 或 v3 簽名,或者簽名使用的金鑰與提供給目前叫用的金鑰不同,only
就會失敗。根據預設,工具會根據
--min-sdk-version
和--max-sdk-version
的值判斷何時應套用這項簽署配置。 -v
、--verbose
- 使用詳細輸出模式。
注意:如果應用程式曾在搭載 Android 12L (API 級別 32) 以下版本的裝置上透過輪替簽署金鑰簽署,則必須使用 --rotation-min-sdk-version 28
搭配 Android 9 (API 級別 28) 的輪替簽署金鑰繼續簽署應用程式。
各簽署者選項
下列選項會指定特定簽署者的設定。如果您僅使用一個簽署者簽署應用程式,則這些為非必要選項。
--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 字元的密碼時,納入指定的字元編碼 (例如
ibm437
或utf-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