先说句废话,今天用腾讯乐固加固应用死活是找不到pc端了,pc端都是一键式简单的很,无奈网页端弄吧,上传上去之后由于加固会把之前的签名删除,需要对加固后的apk重新签名,那么怎么签名,百度了半天怎么说的都有,于是亲自尝试了各种说法,最后总结了一下,希望给他人行个方便
生成密钥
签名之前需要密钥文件,如果已经在as上创建完成那么可以直接进行下面的签名,如果还没有密钥文件就需要创建一个
cmd进入as安装目录下androidstudio\jre\bin执行命令
keytool -genkeypair -keystore xxx.jks -alias one -validity 35600 -keyalg RSA
参数说明:
- -genkeypair 生成一条密钥对(由私钥和公钥组成)
- -keystore 密钥库名字以及存储位置(默认当前目录)
- -alias 密钥对的别名(密钥库可以存在多个密钥对,用于区分不同密钥对)
- -validity 密钥对的有效期(单位: 天)
- -keyalg 生成密钥对的算法(常用RSA/DSA,DSA只用于签名,默认采用DSA)
例
注意这里生成完后会有一个警告
如果直接执行这个命令会报错:keytool 错误: java.lang.Exception: 目标 pkcs12 密钥库具有不同的 storepass 和 keypass。请在指定了 -destkeypass 时重试
更改命令如下:
keytool -importkeystore -srckeystore E:\resign\zyw.jks -destkeypass 123456 -destkeystore E:\resign\zyw.jks -deststoretype pkcs12
这里简单说下在创建jks密钥库的时候为什么要让我们设置 storepass 和 keypass 两个密码?
针对KeyStore有两种不同的操作
- 对store进行添加/查看操作。
- 用它来生成或签名->密钥或证书。
有时候你可能会让别人去查看或者更新你的KeyStore,但是却不想让他用这个KeyStore里面的密钥来签名。
查看密钥库详细信息
cmd进入as安装目录下androidstudio\jre\bin执行命令
keytool -list -v -keystore xxx.jks
对未签名的apk签名
方法一 使用jarsigner进行签名(仅限v1签名)
打开androidstudio安装目录进入androidstudio\jre\bin会看到
打开cmd进入到androidstudio\jre\bin下执行 jarsigner.exe
如果可以运行那么就可以对apk进行签名了,为了方便操作可以将.jks文件和需要签名的apk放到一个文件夹中,接下来执行命令
jarsigner -verbose -keystore xxx.jks -signedjar aSign.apk a.apk Keyalias
需要替换的参数说明:
- xxx.jks:签名文件(注意需要文件的绝对路径)
- aSign.apk:签名后成的签名apk(注意需要文件的绝对路径)
- a.apk:需要签名的apk(注意需要文件的绝对路径)
- Keyalias:jks中你创建的项目别名(就是Key alias)
例:
我将需要的文件放到了E盘的resign文件夹中,CollectInfo就是Key alias,输入密钥库的密码短语就是Key store password,输入CollectInfo的密钥口令就是Key password
执行成功后
方法二 使用apksigner进行签名(默认同时使用V1和V2签名)
打开cmd进入到android sdk 随便选择一个版本就可以,这里我选择的是29.0.3下执行 命令
apksigner sign --ks xxx.jks --ks-key-alias Keyalias test.apk
需要替换的参数说明:
- xxx.jks:签名文件(注意需要文件的绝对路径)
- Keyalias:jks中你创建的项目别名(就是Key alias)
- test.apk:需要签名的apk(注意需要文件的绝对路径)
禁用V2签名
apksigner sign --v2-signing-enabled false --ks xxx.jks --ks-key-alias Keyalias test.apk
例
这里的签名是直接在原apk上直接签名,签名完成后看一下apk文件的修改时间就可以了
v1和v2签名的区别
上面使用 jarsigner 和 apksigner 签名时提到了v1和v2签名,下面说一下二者的区别
在Android Studio中点击菜单 Build->Generate signed apk… 打包签名过程中,
可以看到两种签名选项 V1(Jar Signature) V2(Full APK Signature),从Android 7.0开始, 谷歌增加新签名方案 V2 Scheme (APK Signature);但Android 7.0以下版本, 只能用旧签名方案 V1 scheme (JAR signing)
v1签名:
来自JDK(jarsigner), 对zip压缩包的每个文件进行验证, 签名后还能对压缩包修改(移动/重新压缩文件)。对v1签名的apk/jar解压,在META-INF存放签名文件(MANIFEST.MF, CERT.SF, CERT.RSA), 其中MANIFEST.MF文件保存所有文件的SHA1指纹(除了META-INF文件), 由此可知: v1签名是对压缩包中单个文件签名验证
v2签名:
来自Google(apksigner), 对zip压缩包的整个文件验证, 签名后不能修改压缩包(包括zipalign),对V2签名的apk解压,没有发现签名文件,重新压缩后V2签名就失效, 由此可知: V2签名是对整个APK签名验证
v2签名的优点:
签名更安全(不能修改压缩包)
签名验证时间更短(不需要解压验证),因而安装速度加快
注意: apksigner工具默认同时使用V1和V2签名,以兼容Android 7.0以下版本
zipalign和V2签名
zipalign 是对zip包对齐的工具,使APK包内未压缩的数据有序排列对齐,从而减少APP运行时的内存消耗
打开cmd进入到android sdk 随便选择一个版本就可以,这里我选择的是29.0.3下执行 命令
zipalign -v 4 in.apk out.apk //4字节对齐优化
zipalign -c -v 4 in.apk //检查APK是否对齐
例
如果使用 apksigner 签名,zipalign 在签名之前使用
如果使用 jarsigner 签名,zipalign 在签名之后使用
删除apk签名
如果apk已经签名想重新签名,将apk用zip打开找到 META-INF 文件夹,删除MANIFEST.MF之外的所有其他文件即可。
判断当前apk是否已经签名
1.直接安装到手机上,如果安装成功那么一定是签名之后的,如果安装失败就是没有签名的
2.使用 keytool 验证,执行命令(这是在androidstudio安装目录的\jre\bin下执行)
keytool -printcert -jarfile E:\resign\test.apk
参数说明:
- -printcert 打印证书内容
- -jarfile 已签名的jar文件或apk文件
3.使用 apksigner 验证,执行命令(在android\sdk\build-tools\29.0.3下执行)
apksigner verify --verbose --print-certs test.apk
参数说明:
- -v, --verbose 显示详情(显示是否使用v1和v2签名)
- –print-certs 显示签名证书信息