v1 jar签名
Apk(zip)文件分为3个部分,V1 JAR签名只保护 Contents of ZIP entries 部分:
多证书签名
apksigner sign --ks 1.jks --ks-key-alias key0 --ks-pass pass:123456 --key-pass pass:123456 --next-signer --ks 2.jks --ks-key-alias key0 --ks-pass pass:456789 --key-pass pass:456789 --v1-signer-name signtest --out out.signed.apk input.apk
会生成1个MF文件,多个SF和RSA文件
v2 签名
https://source.android.com/security/apksigning/v2
为了解决v1签名不能全文件的缺陷,Android 7.0 (Nougat) 引入了v2签名方案;
如下图所示,V2 签名会保护整个APK(ZIP)文件,增加一个签名分块ID为 0x7109871a:
V2 大致签名块格式
uint64 0xff8 签名分块大小
uint64 0x709 v2分块大小
0x7109871a v2分块ID
uint32 0x701 长度前缀 signer 1793
uint32 0x6fd 长度前缀 signer 和0x701刚好差4字节
uint32 0x3b3 长度前缀 signed data
uint32 0x60 长度前缀 digests
uint32 0x28 长度前缀 digest item(下面3项的长度总和)
uint32 0x103 signature algorithm ID
uint32 0x20 长度前缀 digest 32
char[0x20] digest content
uint32 0x373 长度前缀 X.509 certificates
uint32 0x333 长度前缀 X.509 certificate item
char[0x333] certificate content
...
uint64 0xff8 签名分块大小
APK Sig Block 42 v2签名Magic
https://github.com/xyzAsian/AndroidSign
上面👆🏻链接是从apk中手动解析v2签名结构读取签名证书MD5的例子,有兴趣的朋友可以对照官方文档结构继续补全;
V3签名
https://source.android.com/security/apksigning/v3
Android 9 支持 APK 密钥轮替,使应用能够在 APK 更新过程中更改其签名密钥:
- v3 方案增添了有关受支持的 SDK 版本和 proof-of-rotation 结构的信息
- v3 签名会存储为一个“ID-值”对,其中 ID 为 0xf05368c0
通俗解释就是Android9以上支持更换换签名秘钥,不影响覆盖安装:
假设APP先使用1.jks签名得到APP.1.sign.apk,然后再使用2.jks签名得到APP.2.sign.apk,APP.2.sign.apk无法覆盖安装APP.1.sign.apk(签名不一致),但是可以增加一个中间版本使用v3签名得到APP.1.2.sign.apk,先使用APP.1.2.sign.apk覆盖安装APP.1.sign.apk,再使用APP.2.sign.apk覆盖安装APP.1.2.sign.apk 即可更换签名。(需要minSdk >= Android9,旧版本不认v3签名)
秘钥轮替使用方法如下:
#!/bin/bash
rm -f ./sleepin-release-lineage
apksigner rotate \
--out ./sleepin-release-lineage \
--old-signer --ks 1.jks --ks-key-alias key0 --ks-pass pass:123456 --key-pass pass:123456 \
--new-signer --ks 2.jks --ks-key-alias key0 --ks-pass pass:456789 --key-pass pass:456789 \
apksigner sign \
--ks 1.jks --ks-key-alias key0 --ks-pass pass:123456 --key-pass pass:123456 \
--next-signer \
--ks 2.jks --ks-key-alias key0 --ks-pass pass:456789 --key-pass pass:456789 --v1-signer-name signtest \
--lineage ./sleepin-release-lineage \
--out out.signed.1.rotate.2.apk input.apk
V4签名
https://source.android.com/security/apksigning/v4
Android 11 通过 APK 签名方案 v4 支持与流式传输兼容的签名方案。Android 11 将签名存储在单独的 <apk name>.apk.idsig 文件中。v4 签名需要 v2 或 v3 签名作为补充。
v4签名是为了兼容流式传输设计的签名方案,和其他签名最大的不同是,v4签名单独存放在<apk name>.apk.idsig文件中,且如果v4验证失败则主动降级使用v2或者v3签名继续校验;而v3 v2签名若校验不通过则直接退出安装,如下图所示: