签名方法和验证
签名方法
目前Android7.0以下的手机使用v1版本签名,7.0以上手机支持v1、v2, 更高版本的手机可能支持v3、v4;早期v1签名是使用jdk自带的jarsigner,现在已经不推荐使用; 目前推荐使用Android SDK自带的apksigner,在Android SDK安装目录下。
签名工具目录
SDK/build-tools/版本号/apksigner.bat (或SDK/build-tools/版本号/lib/apksigner.jar),版本号需大于等于25。
使用 apksigner 工具为 apk 签名的语法如下(两种签名方式)
apksigner sign --ks keystore.jks [signer_options] app-name.apk
apksigner sign --key key.pk8 --cert cert.x509.pem [signer_options] app-name.apk
在您使用 apksigner 工具为 apk 签名时,必须提供签名者的私钥和证书。您可以通过两种不同的方式添加此信息:
- 使用 --ks 选项指定密钥库文件。
- 使用 --key 和 --cert 选项分别指定私钥文件和证书文件。私钥文件必须使用 PKCS #8 格式,证书文件必须使用 X.509 格式。
- 使用 [signer_options] 可指定应用于签名者的基本设置。
重要选项
以下选项指定要应用于签名者的基本设置。
设置 | 说明 |
---|---|
--out | 您将要保存已签名 apk的位置。如果未明确提供此选项,则 apk 软件包将就地签名,并替换输入的 apk文件。 |
--min-sdk-version | apksigner 用来确认 apk 签名将通过验证的最低 Android 框架 API 级别。该级别值越高,表示该工具在为应用签名时可使用的安全参数越强,但这会限制 apk 只能用于搭载更新版本 Android 的设备。 |
--max-sdk-version | apksigner 用来确认 apk 签名将通过验证的最高 Android 框架 API 级别。默认情况下,该工具会使用尽可能高的 API 级别。 |
--v1-signing-enabled | 确定 apksigner 是否会使用基于 JAR 的传统签名方案为给定的 apk 软件包签名。默认情况下,该工具会使用 --min-sdk-version 和 --max-sdk-version 的值来决定何时采用此签名方案。 |
--v2-signing-enabled | 确定 apksigner 是否会使用 apk 签名方案 v2 为给定的 apk 软件包签名。默认情况下,该工具会使用 --min-sdk-version 和 --max-sdk-version 的值来决定何时采用此签名方案。 |
--v3-signing-enabled | 确定 apksigner 是否会使用 apk 签名方案 v3 为给定的 apk 软件包签名。默认情况下,该工具会使用 --min-sdk-version 和 --max-sdk-version 的值来决定何时采用此签名方案。 |
--v4-signing-enabled | 确定 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 | 使用详细输出模式。 |
密钥和证书选项
以下选项用于指定签名者的私钥和证书。
设置 | 说明 |
---|---|
--ks | 签名者的私钥和证书链包含在给定的基于 Java 的密钥库文件中。如果文件名设为 "NONE",则包含密钥和证书的密钥库不需要指定文件,某些 PKCS#11 密钥库就是这种情况。 |
--ks-key-alias | 表示签名者在密钥库中的私钥和证书数据的别名的名称。如果与签名者关联的密钥库包含多个密钥,则必须指定此选项。 |
--ks-pass | 包含签名者私钥和证书的密钥库的密码。您必须提供密码才能打开密钥库。apksigner 工具支持以下格式:1)pass:- 密码与 apksigner sign 命令的其余部分一起提供(内嵌在其中)。2)env: - 密码存储在给定的环境变量中。3)file: - 密码存储在给定文件中的某一行。4)stdin - 密码作为标准输入流中的某一行提供。这是 --ks-pass 的默认行为。 |
注意事项
如果一个文件中包含多个密码,请分别在不同的行中指定这些密码。apksigner 工具会根据您指定 APK 签名者的顺序将密码与签名者相关联。
如果您为签名者提供了两个密码,apksigner 会将第一个密码视为密钥库密码,将第二个密码视为密钥密码。
使用 release.jks(密钥库中唯一的密钥)为 apk 签名:
$ apksigner sign --ks release.jks app.apk
使用私钥和证书(存储为不同的文件)为 apk 签名:
$ apksigner sign --key release.pk8 --cert release.x509.pem app.apk
签名保留源文件,生产新文件:
$apksigner sign --key release.pk8 --cert release.x509.pem --out app.sign.apk app.apk
签名禁用v3、v4
$ apksigner sign --ks release.jks --v3-signing-enabled false --v4-signing-enabled false app.apk
签名指定sdk version(sdk version会影响生产的签名版本)
$ apksigner sign --ks release.jks --min-sdk-version 20 --max-sdk-version 27 app.apk
签名验证和查看方法
人工简单查看
解压apk/META-INF/XXXX.SF(如CERT.SF,不是MANIFEST.SF),查看开始部分,如果不包含X-Android-APK-Signed字样则为v1, 如:
Signature-Version: 1.0
SHA1-Digest-Manifest-Main-Attributes: NdvTTYSDLv+xfCdISs2OUVv3OXY=
Created-By: 1.6.0_37 (Sun Microsystems Inc.)
SHA1-Digest-Manifest: sN1jczINBspGueVoYodPfvNRYKA=
包含X-Android-APK-Signed字样,则冒号后面跟的版本就是签名版本,如下面是v1和v2版本
Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA1-Digest-Manifest: EsSraWdS5nUZen7L+SDZDNTr230=
X-Android-APK-Signed: 2
包含X-Android-APK-Signed字样,则冒号后面跟的版本就是签名版本,如下面是v2和v3版本
Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA1-Digest-Manifest: EsSraWdS5nUZen7L+SDZDNTr230=
X-Android-APK-Signed: 2, 3
工具查看(通过工具会输出详细的签名信息)
在SDK/build-tools/版本(如30.0.2)/apksigner.bat或SDK/build-tools/版本(如30.0.2)/lib/apksigner.jar两种工具。
- 工具一使用:
SDK/build-tools/版本(如30.0.2)/apksigner.bat verify --verbose xxx.apk
- 工具二使用:
java -jar SDK/build-tools/版本(如30.0.2)/lib/apksigner.jar --verbose xxx.apk
示例(v1+v2):
E:\Android\Sdk\build-tools\30.0.2\apksigner.bat verify --verbose .\cdd.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
示例(v1):
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): false
Verified using v3 scheme (APK Signature Scheme v3): false
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Nuer of signers: 1
更详细说明
https://developer.android.com/studio/command-line/apksigner?hl=zh-cn#options