一、签名方式
在Android中,所有 APK 必须先使用证书进行签名才能安装到设备上。当前主流的有两种签名选项 V1(Jar Signature) 、V2(Full APK Signature)。从Android 7.0开始, 谷歌增加新签名方案 V2,但Android 7.0以下版本, 只能用旧签名方案 V1。jarsigner使用java自带的jar签名,签名方案只能v1。apksigner是Android特有的签名,支持多种签名方案(v1~v4)。
- V1签名
对zip压缩包的每个文件进行验证, 签名后还能对压缩包修改。对V1签名的apk解压后,在META-INF存放签名文件(MANIFEST.MF, CERT.SF, CERT.RSA),其中MANIFEST.MF文件保存所有文件的SHA1指纹。 - V2签名
对zip压缩包的整个文件验证, 签名后不能修改压缩包(包括zipalign),对V2签名的apk解压,没有发现签名文件,重新压缩后V2签名就失效。V2签名更安全因为不能修改压缩包,签名验证时间更短,不需要解压验证,安装速度加快。apksigner工具默认同时使用V1和V2签名。 - V3签名
v3 是在 Android 9 中引入的。Android 9 支持 APK 密钥轮替,这使应用能够在 APK 更新过程中更改其签名密钥。为了实现轮替,APK 必须指示新旧签名密钥之间的信任级别。 - V4 签名
v4 是在 Android 11 中引入的。v4 支持与流式传输兼容的签名方案。v4 签名需要 v2 或 v3 签名作为补充。 v4同样是为了新功能而出现的: ADB 增量 APK 安装。
二、签名步骤
1.工具文件
Android Studio在Debug时,对App签名都会使用一个默认的密钥库,默认在C:\Users\用户名.android\debug.keystore
jarsigner 位于JDK/bin
apksigner 位于Android SDK/build-tools/SDK版本
apktool 官网下载apktool.bat和apktool.jar
2.查看密钥库
keytool -list -v -keystore debug.keystore
3.移除现有的签名
使用Android SDK中的apktool工具来解包APK,移除现有的签名。
apktool命令解包一个APK文件时,apktool会自动移除该APK的签名。这是因为APK的签名是保存在META-INF目录下的,而当你使用apktool d(即decode)命令解包APK时,apktool会解析APK文件并提取出其中的资源、代码等,但不会保留签名信息。
apktool d -f your_app.apk -o output_dir
4.重新打包APK
解包完成后,重新打包APK。
apktool b output_dir -o unsigned.apk
5.zipalign和V2签名
zipalign 是对zip包对齐的工具,使APK包内未压缩的数据有序排列对齐,从而减少APP运行时内存消耗。zipalign可以在V1签名后执行,但zipalign不能在V2签名后执行,只能在V2签名之前执行
位于Android SDK/build-tools/SDK版本/zipalign.exe
- 对齐
zipalign -p -f -v 4 待签名.apk 对齐后.apk
- 检查APK是否对齐
zipalign -c -v 4 in.apk
6.签名
- jarsigner
jarsigner -keystore 秘钥文件 -storepass 密钥库的密码 -keypass 私钥密 <apk_file>.apk <alias>
- apksigner
apksigner sign --ks 密钥文件 --ks-key-alias 密钥别名 --ks-pass pass:密码 --key-pass pass:密码 --out 签名.apk 对齐.apk
若密钥库中有多个密钥对,则必须指定密钥别名,若密钥库有一个密钥对,则可省略
禁用V2签名
apksigner sign --v2-signing-enabled false --ks 密钥库名 xxx.apk
7.签名验证
- keytool
keytool -printcert -jarfile MyApp.apk
- apksigner
apksigner verify -v --print-certs xxx.apk