• 作者:老汪软件技巧
  • 发表时间: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、相关文档