Android SDK 构建工具 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
sign 命令具有以下选项。
常规选项
以下选项指定要应用于签名者的基本设置
--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>
- APK 的轮换签名密钥应使用的最低 API 级别以生成 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 尚未具有 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 通常通过使用控制台的默认字符集转换密码来加密密钥库。默认情况下,
apksigner
会尝试使用密码的几种形式进行解密- Unicode 形式
- 使用 JVM 默认字符集编码的表单
- 在 Java 8 及更早版本中,使用控制台的默认字符集编码的表单
在 Java 9 中,
apksigner
无法检测控制台的字符集。当使用非 ASCII 密码时,您可能需要指定--pass-encoding
。对于 keytool 在不同操作系统或不同区域设置中创建的 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 提供程序的名称。默认情况下,
apksigner
使用优先级最高的提供程序。 --ks-provider-class <class-name>
- 请求签名者的 KeyStore 实现时要使用的 JCA 提供程序的完全限定类名。此选项用作
--ks-provider-name
的替代方法。默认情况下,apksigner
使用使用--ks-provider-name
选项指定的提供程序。 --ks-provider-arg <value>
- 作为 JCA 提供程序类的构造函数的参数传入的字符串值;该类本身由
--ks-provider-class
选项定义。默认情况下,apksigner
使用类的零参数构造函数。 --key <filename>
- 包含签名者的私钥的文件的名称。此文件必须使用 PKCS #8 DER 格式。如果密钥受密码保护,则
apksigner
会提示您使用标准输入输入密码,除非您使用--key-pass
选项指定其他类型的输入格式。 --cert <filename>
- 包含签名者的证书链的文件的名称。此文件必须使用 X.509 PEM 或 DER 格式。
验证命令
apksigner
verify 命令具有以下选项。
--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 签名
使用 release.jks
签署 APK,它是 KeyStore 中唯一的密钥
$ 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