您可以使用 Android SDK 構建工具的修訂版 24.0.3 及更高版本中提供的 apksigner
工具爲 APK 簽名,並確保 APK 的簽名能夠在 APK 支持的所有版本的 Android 平臺上成功通過驗證。本頁提供了有關如何使用該工具的簡短指南,並可作爲查閱該工具支持的不同命令行選項的參考文檔。如需有關如何使用 apksigner
工具爲 APK 簽名的更完整說明,請參閱爲您的應用簽名指南。
注意:如果您在使用
apksigner
爲 APK 簽名後又對 APK 做了更改,則 APK 的簽名將會失效。因此,要使用zipalign
等工具,您必須在爲 APK 簽名之前使用。
用法
爲 APK 簽名
使用 apksigner
工具爲 APK 簽名的語法如下:
apksigner sign --ks keystore.jks | --key key.pk8 --cert cert.x509.pem [signer_options] app-name.apk
在您使用 apksigner
工具爲 APK 簽名時,必須提供簽名者的私鑰和證書。您可以通過兩種不同的方式添加此信息:
- 使用
--ks
選項指定密鑰庫文件。 - 使用
--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
工具支持的每個命令的選項集。
簽名命令
常規選項
以下選項指定要應用於簽名者的基本設置:
--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 級別。
--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
的值來決定何時應用此簽名方案。
--v4-no-merkle-tree
默認情況下,.idsig
文件包含 APK 文件的完整 Merkle 樹。使用此標誌時,apksigner 會生成一個 APK 簽名方案 v4 .idsig
文件,且不會嵌入完整的 Merkle 樹。此選項會減小簽名文件的大小,但會強制任何需要該樹的工具重新計算大小, 或者再次調用 apksigner
工具。
-v
,--verbose
使用詳細輸出模式。
每個簽名者的選項
以下選項用於指定特定簽名者的配置。如果您僅使用一個簽名者爲應用簽名,則無需使用這些選項。
--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 簽名者的順序將密碼與簽名者相關聯。如果您爲簽名者提供了兩個密碼,apksigner
會將第一個密碼視爲密鑰庫密碼,將第二個密碼視爲密鑰密碼。
--pass-encoding <charset>
在嘗試處理包含非 ASCII 字符的密碼時,請添加指定的字符編碼(例如,ibm437
或 utf-8
)。
密鑰工具通常使用控制檯的默認字符集轉換密碼,以加密密鑰庫。默認情況下,apksigner
會嘗試使用多種形式的密碼進行 解密:Unicode 編碼形式、使用 JVM 默認字符集編碼的形式,以及使用控制檯的默認字符集編碼的形式(在 Java 8 及更早 版本上)。在 Java 9 上,apksigner
無法檢測控制檯的字符集。因此,當使用非 ASCII 密碼時,您可能需要指定 --pass- encoding
。對於密鑰工具在不同操作系統或不同語言區域中創建的密鑰庫,您可能也需要指定此選項。
--key-pass <input-format>
簽名者私鑰的密碼。如果私鑰受密碼保護,則需要該密碼。apksigner
工具支持以下格式:
pass:<password>
- 密碼與apksigner sign
命令的其餘部分一起提供(內嵌在其中)。env:<name>
- 密碼存儲在給定的環境變量中。file:<filename>
- 密碼作爲單行存儲在給定文件中。stdin
- 密碼作爲單行在標準輸入流中提供。這是--key-pass
的默認行爲。
注意:如果您在一個文件中包含多個密碼,請在不同的行中指定這些密碼。
apksigner
工具會根據您指定 APK 簽名者的順序將密碼與簽名者相關聯。如果您爲簽名者提供了兩個密碼,apksigner
會將第一個密碼視爲密鑰庫密碼,將第二個密碼視爲密鑰密碼。
--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
會使用該類的 0 參數構造函數。
--key <filename>
包含簽名者私鑰的文件的名稱。該文件必須使用 PKCS #8 DER 格式。如果密鑰受密碼保護,則除非您使用 --key-pass
選項指定其他類型的輸入格式,否則 apksigner
會提示您使用標準輸入格式輸入密碼。
--cert <filename>
包含簽名者證書鏈的文件的名稱。此文件必須使用 X.509 PEM 或 DER 格式。
驗證命令
--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
將警告視爲錯誤。
示例
爲 APK 簽名
使用 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 簽名
檢查 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