- 作者:老汪软件技巧
- 发表时间:2024-08-21 07:01
- 浏览量:
本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
1、签名简介
应用签名是一种数字签名,主要用来验证应用的完整性以及发布者身份认证。
在Android应用发布之前非常重要的一环就是应用签名,Android系统要求所有APK在安装到设备上或更新之前都必须使用证书进行数字签名,Android系统会验证应用的签名。
版本更新时,新版本APK必须使用相同密钥签名,否则无法覆盖安装;如果签名变更,也无法更新应用,必须卸载重新安装。可见签名对Android应用发布的重要性。
2、签名文件
在Android中,签名一般包含三个信息,密钥库、秘钥和证书,在应用首次发布时,我们可以借助Android Studio工具来生成它们。
选择Build > Generate Signed Bundle / APK开始生成密钥库和秘钥。
选择签名类型,这里选择APK,然后点击Next按钮。
点击Create new按钮来创建新的秘钥库文件,如果已有秘钥库文件,选择对应路径即可。
在表单中填写如下两部分信息。
密钥库:密钥库路径(Key store path):输入一个存储密钥库文件的路径并命名,例如my-release-key.jks。密钥库密码(Password):输入并确认密钥库的密码。秘钥:秘钥别名(Alias):为新的密钥创建一个别名,例如my-key-alias。秘钥密码(Key password):输入并确认密钥的密码。通常与密钥库的密码相同,但也可以选择不同的密码。有效期(Validity (years)):设置密钥的有效期,例如25年(通常是设置一个较长的时间)。证书(Certificate):填写证书信息,包括名字、组织单位、组织、市、州/省和国家代码(例:CN)。
填写完所有信息之后,点击OK按钮即可创建密钥文件。
3、应用签名
密钥库和秘钥创建成功之后,会自动回到上一页并填充我们刚才填好的签名信息。
然后点击Next按钮,选择需要签名的构建变体。
一般选择release,也可以多选。
点击Create按钮即开始构建并签名了。
打包构建完成后,签名好的APK文件在app/变体/目录下:
4、签名配置
上面可视化的签名打包方式,一般适用于临时构建,或应用渠道较少的场景。
好处是操作方便,不易泄露秘钥的密码等关键信息。
不足的是不适用自动化构建(CI/CD)场景,以及多渠道构建场景下,可能会出现渠道选漏的情况。
如果在工作中,渠道包是自动化构建的,那么就需要在build.gradle文件中进行签名配置了。
签名配置步骤如下:
第一步,在项目的根目录下创建一个名为keystore.properties的文件,并在其中包含以下信息:
storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation
第二步,在build.gradle文件中,按如下方式加载keystore.properties文件(必须在android代码块前面):
import java.util.Properties
import java.io.FileInputStream
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
android {
...
}
...
第三步,在signingConfigs{ }中配置存储在keystoreProperties文件中的签名信息:
android {
signingConfigs {
create("config") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
...
}
第四步,在构建类型buildTypes中引用signingConfigs{ }中的签名配置:
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ...
}
}
最后点击Sync同步即可。
这样就可以使用命令./gradlew assembleRelease来进行批量签名打包了。
在本地开发阶段,Android Studio会自动生成Debug签名,无需手动配置,但是Debug签名无法用于应用发布。
5、签名方案5.1、介绍
v1签名 (Jar签名):传统的JAR签名机制,验证速度慢,但兼容早期版本(7.0以前)。v1 签名不保护APK的某些部分,例如ZIP元数据。
v2签名 (APK签名方案):Android 7.0引入,基于Merkle哈希树,比v1签名更安全,验证速度更快,支持Android 7.0及以上。
v3签名 (APK签名方案):Android 9.0引入,继承了v2签名的性能优势和安全性,并对整个APK文件进行签名检查,还增加了秘钥轮换能力,就是允许对应用的签名密钥进行更新,而不会影响应用的安装和更新。
v3.1签名 (APK签名方案):Fix版本,Android 13.0引入,修复了v3方案中秘钥轮换的已知问题。
v4签名 (APK签名方案):Android 11.0引入,主要是在验证方面,提升了APK增量更新和安装速度。
美团基于v2签名方案的多渠道打包方案(walle)原理是:打包过程中在META-INF目录下添加空文件用来作为渠道的唯一标识。
在v3签名方案中,基于 Merkle 哈希树对整个APK文件进行签名检查,确保APK文件的完整性,对APK进行的任何修改都会使APK签名作废,从而导致安装失败。而META-INF作为APK的一部分(签名块),自然也是会被签名检查,且不能修改的。
所以这也是walle为什么会在Android 9.0(v3)以后失效的原因。
5.2、选择签名方案
那这几个签名方案怎么选呢?不妨先看看市面上大型APP它们是怎么选的?
APP签名方案
微信
v1、v2
淘宝
v1、v2
拼多多
v1、v2
在查看了微信、淘宝和拼多多的签名方案之后,发现它们都惊人的一致。
v1、v2的兼容性和安全性不错,一般是必选的,v3、v4有新特性,性能较好,可以结合自己的项目按需配置(v4需要与v2或v3结合使用)。
5.3、配置签名方案
确定了签名方案之后,就是怎么让签名方案生效了,这就需要在build.gradle文件中添加签名方案配置了。
示例配置如下:
// 配置签名方案
buildTypes {
release {
// ...
// 启用v1签名
v1SigningEnabled true
// 启用v2签名
v2SigningEnabled true
// 启用v3签名
v3SigningEnabled true
// 启用v4签名
v4SigningEnabled true
}
}
新的签名格式向后兼容,比如使用v3签名方案的APK可以在5.0的设备上安装,前提是包含v1签名方案。
5.4、APK签名验证流程
以v4签名为例,验证流程如下:
校验APK文件中是否存在v4签名文件,存在则继续确认v2或v3方案,因为v4签名本身不足以验证APK的完整性和来源,所以需要与v2或v3方案结合使用,验证通过则允许安装;如果不存在v4签名文件或验证不通过则继续走v3签名验证流程。v3签名方案的验证流程,先校验APK文件中是否存在v3签名方案的签名块,存在且校验通过则允许安装,否则拒接安装;如果不存在则继续走v2签名验证流程。v2签名方案的验证流程,先校验APK文件中是否存在v2签名方案的签名块,存在且校验通过则允许安装,否则拒接安装;如果不存在则继续走v1签名验证流程。v1签名方案的验证流程,验证通过则允许安装,否则拒接安装。
在v2、v3、v4签名验证流程中,最大的区别在于,v2、v3的签名规则验证不通过会直接拒接安装,v4则是继续往下走。
5.5、查看应用签名方案
查看一个已经签名的APK文件使用了哪种签名方案,通常需要一些工具来解析和分析APK的签名信息。
我们可以使用Android SDK提供的apksigner工具,apksigner主要用于签名和验证APK文件,通过apksigner可以查看APK的签名信息。
5.5.1、配置环境
在使用apksigner之前,需要先确认环境变量是否配置正确。
以macOS系统为例:
找到~/.bash_profile 或 ~/.bashrc 文件,进入编辑。
在文件末尾添加以下内容:
export PATH=$PATH:~/Library/Android/sdk/build-tools/33.0.1
Android SDK路径和版本号替换成你自己的。
然后执行命令刷新文件是环境变量配置立即生效:
source ~/.bashrc
// or
source ~/.zshrc
5.5.2、apksigner使用
配置好环境之后,执行以下命令:
apksigner verify --verbose --print-certs /Users/yechao/AndroidStudioProjects/GradleX/app/release/app-release.apk
apk地址换成你自己的。
输出如下图:
在输出信息中,可以看到v1 scheme、v2 scheme、v3 scheme和v4 scheme的相关信息,true表示该签名方案开启,false表示关闭,默认开启v1、v2方案。
6、获取签名信息
在上传应用市场或集成第三方SDK的时候,通常会要求填写APK相关的信息来进行验证,其中包括签名信息,比如SHA-1、SHA-256。
下面来介绍几种常用的提取签名信息的方式。
6.1、signingReport
signingReport是Gradle插件提供的一个能力,用于生成签名报告。
在Gradle面板中找到signingReport任务,app > Tasks > android > signingReport。
在执行signingReport任务前,确认在build.gradle文件中已经正确配置了signingConfigs。
双击执行signingReport任务,在构建日志中会同时输出debug和release签名信息。
如下图:
6.2、keytool
keytool是Java SDK自带的一个工具,可以用来查看密钥库文件(例如.jks或.keystore)中的签名信息,包括SHA-1指纹。
keytool 支持两种文件方式查看签名信息,分别是keystore和apk。
6.2.1、keystore方式
命令如下:
keytool -list -v -keystore your-keystore-file.jks
输出:
6.2.2、apk方式
命令如下:
keytool -printcert -jarfile your-apk-file.apk
输出:
7、签名安全
如果签名文件丢失或者损坏,唯一的解决办法就是生成新的签名文件,但是会导致应用版本更新问题,需要用户卸载重装,沉没成本较大。
所以,签名文件和签名相关信息一定要保存好,定期做好备份。
一些安全建议:
8、总结
本章我们了解了Android应用签名的重要性、具体的实现方法,和签名方案的介绍及方案选择,还有签名验证流程,最后是一些关于签名安全的建议。
9、GitHub
/yechaoa/Gra…
10、相关文档