前言
最近帮测试做了一点对于签名的需要,明天就和各位同学简略聊一聊对于签名的那些事儿。
如果问到 Android 为什么须要签名?大家都可能想到官网的解释:
Android 零碎要求所有 APK 必须先应用证书进行数字签名,而后能力装置到设施上进行更新。
这是一个比拟含糊的解释,简略来说,有了签名,就能够让 App 和开发者绑定。
毕竟,利用那么多,别的开发者也有可能盗用你的代码,这个时候,包名和你雷同,代码和你雷同,怎么辨别你的 App 和这些人的 App 不是同一个呢?
这个时候数字签名就派上用场了。
一、签名根底
想要彻底理解签名常识,咱们得理解以下常识:
- 音讯摘要
- 数字签名
- 加密
- 数字证书
这一系列的常识各位可能在学习网络的时候或多或少的接触过。
咱们简略的学习一下这些常识:
1. 音讯摘要
音讯摘要经常被被称为数字摘要或者数字指纹,定义如下:
在原来的数据根底上,通过一个单向的 Hash 计算,失去一个固定的 Hash 值,这就是音讯摘要。
常见的摘要算法都有 MD5、SHA-1 和 SHA-256,特点如下:
- 长度固定,与内容长度无关:比方 MD5 是 128 位、SHA-1 是 160 位、SHA-256 是 256 位。
- 看似随机,其实不随机:同内容两次摘要得出的后果统一
- 单向:只能从原数据得出摘要,不能从音讯摘要得出原来的数据
- 优良的摘要算法很难 Hash 碰撞
基于此,音讯摘要经常会被用来查看内容的完整性。
比方咱们下载终点读书,音讯摘要的用法如下:
- 计算摘要:App 会针对本人的文件信息计算出一个数字摘要比方
123**...**123
- 下载 App
- 验证摘要:对下载的 App 再次计算摘要,比方得出的也是
123**...**123
,和之前的数字摘要一比照,这就代表我从服务器下载的内容是残缺的,能够失常应用
当然,上面值波及了摘要局部,其余过程,咱们前面剖析。
2. 加密算法
什么是加密?
百科是这么解释的:
将明文信息扭转为难以读取的密文内容,使之不可读的过程。只有领有解密办法的对象,经由解密过程,能力将密文还原为失常可读的内容。
所以啊,加密办法失去的密文是能够转变为明文的,像信息摘要算法比方 MD5 得进去的后果是不可逆的,所以面试官问你们什么事加密算法的时候,你可不能把 MD5 说进去!
加密算法分为两大类,对称加密 和非对称加密。
2.1 对称加密
对称加密在加密和解密的时候应用的同一把钥匙:
图片来自《一文彻底搞懂加密、数字签名和数字证书!》
2.2 非对称加密
非对称加密是应用公钥 / 私钥中的公钥来加密明文,而后应用对应的私钥来解密密文的过程:
图片来自《一文彻底搞懂加密、数字签名和数字证书!》
简略比照一下对称加密和非对称秘密:
非对称加密 | 对称加密 | |
---|---|---|
速度 | 慢 | 快 |
效率 | 低 | 高 |
安全性 | 高 | 低 |
常见算法 | RSA\DH | AES\DES\IDEA |
2.3 应用场景
学过网络的同学应该都理解,在 Https 的传输过程中,客户端和服务端应用非对称加密生成对称加密的密钥,而后用对称加密传输网络中的数据。
比方我上大学那会儿,每个月的月尾我和我妈的对话是这样的:
网络环境是凋谢的,万一这时,有一个黑客监听了我和我妈的对话,过程就变成了这样:
在我发卡号的时候,黑客将我的卡号改成了它的卡号,于是我的生活费变成了他的生活费。
为了防止这种状况,于是我和我妈约定好了,每次发送前,应用对称加密对音讯进行加密,承受音讯的时候应用密钥解密,过程就变成了这样:
中间人再也不能获取到音讯了,看似一点问题都没有,然而我和老妈之间如何确定密钥呢?
密钥总要在互联网之间进行传输的,有传输就有被中间人截获的危险,一旦被截获,钱可就没了!
为了解决对称加密钥匙传输的问题,我和老妈用上了非对称加密,像这样:
即便这样,还是有问题存在:
- 怎么能力确认我取得的公钥来自老妈?
- 如何确定音讯的确来自老妈?
解决这两个问题也很简略,一是数字签名,二就是数字证书。
3. 数字签名
数字签名的作用是为了音讯的完整性。
在非对称加密的体系下,音讯的发送过程是这样的,还是下面的例子:
数字签名的过程是这样的:
- 我发送音讯前,利用 Hash 算法针对数据得出一个摘要
- 我应用老妈的公钥对摘要内容进行加密,连同对称加密的数据一起发送过来
- 老妈接管到音讯后,先利用对称密钥对内容解密,再进行 Hash 计算得出摘要
- 老妈应用私钥将摘要内容解密,和再次计算得出的摘要作比照,统一就代表音讯无误
下面的这种场景其实有点不妥,数字签名个别用在证书上,协商好对称密钥当前个别不会进行音讯完整性校验了,不过大伙只有理解数字签名要来校验音讯完整性就好。
截止当初,还有最初一个问题,我无奈确认获取的公钥的确来自老妈。
3. 数字证书
证书的作用很简略,证实公钥的身份。
就像在事实中,大家都是怎么证实本人的身份的?
没错,是身份证。你有没有发现,每张身份证,会有三种信息:
- 本身的信息
- 购置身份证的派出所
- 有效期
对应的数字证书也有很多内容:
- CA:证书的颁发机构
- 证书的有效期
- 公钥
- 证书的授予对象
CA 将这些内容利用 CA 的私钥进行签名,用户应用 CA 的公钥验签,从而证实公钥的身份。
常见的证书分为两种:
- 签名证书:由 CA 机构颁发,绝大部分网站都采纳的这种形式
- 自签名证书:由服务器本人颁发给本人
重回之前的例子,老妈只须要将本人的签名证书发给我,我就能够获取她的公钥,之后就能够失常的通信。
二、Android 签名机制
在 Android 中,也须要应用数字证书做数字签名,数字证书中公钥对应的私钥由开发者持有。
对于私钥和证书的生成形式,能够查看:
《Android 官网文档》
在 Android Studio 中,最终会生成一个 .jks 的文件,晚期 Eclipse 是 .keystore,它们都是用作证书和私钥的二进制文件。
App 如果应用了一种私钥签名,另外一个私钥签名的文件将无奈装置或笼罩老的版本,这样做是为了避免曾经装置的 App 被歹意的第三方笼罩。
1. Android 签名机制的异同点
Android 中数字签名的生成和一般的数字签名并没有很大的区别。
然而进行数字签名的证书能够采纳自签名证书,即不须要权威证书颁发机构(CA)来做背书,因为它的作用是用来标识应用程序的开发者,下载的用户并不需要这个证书来下载该 App。
2. Debug 和 Relase 的签名
当咱们在 IDE 中运行或调试我的项目时,AS 会主动应用 Android SDK 工具生成的调试证书为咱们的利用签名,门路为 $HOME/.android/debug.keystore
,然而利用商店可不承受应用调试证书公布的利用签名。
打包 Release 时,咱们个别会在 app
模块中的 build.gradle
进行配置:
android {
...
signingConfigs {
release {storeFile file("release.keystore")
storePassword "******"
keyAlias "******"
keyPassword "******"
}
}
}
这些都是咱们生成 .jks
或者 .keystore
须要生成的参数。
三、签名计划
目前 Android 反对以下四种利用签名计划:
- v1 计划:基于 JAR 签名
- v2 计划:Android 7.0 引入,改变大
- v3 计划:Android 9.0 引入,基于 v2 的降级
- v4 计划:Android 11.0 引入,用来反对 ADB 增量 APK 装置
1 v1 计划
v1 是一个陈词滥调的签名了,签名过程也很简略。
咱们如果选中一个任意签名后的 apk 进行解压,会找到一个 META-INF 文件,这个文件里个别会有以 MF、SF 和 RSA 结尾的文件,如图:
这些文件在 v1 签名流程中是这样的:
验证过程在 Apk 装置的过程中:
整个过程清晰明了,但 v1 有两个问题:
第一个问题是签名校验慢,要针对 Apk 中所有的文件进行校验,这会连累老设施的安装时间。
第二个问题是仅针对 ZIP 条目校验,META-INF 文件不会计入校验过程。这样会导致即便我 Apk 曾经签过名,工程师也能够挪动条目程序并从新压缩,也能够批改 META-INF 文件下的内容,带来一些安全隐患,晚期的多渠道打包就是在这里做的文章。
2. v2 计划
v2 是 Android 签名计划的一大步,它解决了 v1 遗留的签名校验慢和完整性的问题。
咱们先来看一下 v2 的组成部分:
v1 的组成部分其实就和 Before signing 那一块儿一样,v2 多了红色区域,咱们称之为 APK 签名分块。
从爱护的内容来看,v1 仅爱护内容 1,v2 爱护的区域有 1、3、4 和 2 的 signed data
区域,signed data
是 1、3 和 4 得进去的摘要等信息。
签名过程
就一个 App 而言,它可能有一个或者多个签名者,对于每个签名者而言,都会进行签名过程。
v2 没有对每个文件都进行计算,而是针对的所有字节。它将 1、3 和 4 区域都拆分成了大小为 1MB 的间断块,计算形式如下:
- 每个小块都按:字节
0xa5
+ 块字节长度 + 块内容 进行计算 - 每个 1、3 和 4 块都按:字节
0xa5
+ 块数 + 小块摘要 进行计算
最初,将这些一个或者多个签名者的摘要、证书等信息都打包到 Apk 中。
验签过程
v2 计划的 APK 验证过程是这样的:
- 找到 APK 签名分块区域
- 每找到一个签名者,都会验证:签名算法、信息摘要、证书和公钥
- 所有的签名者都验证通过了,APK 验证才会通过
3. v3 计划
v3 计划建设在 v2 的根底上,指标是解决在更新过程中更改签名密钥的问题。
所以 APK 签名分块中 增加了两局部内容:
- Proof-of-rotation: 一个存在替换的所有旧签名证书的链表,根节点是最旧的证书
- SDK 版本反对
v3 和 v2 的签名过程和验证过程简直统一,就不写进去了。
4. v4 计划
如果同学们常常玩一些主机游戏,能够发现,在 PS5 或者 Swtich 上,一些游戏即便没有装置实现,咱们也能够关上游戏玩一些基本功能,比方我以前常玩的 NBA 2k 系列。
Android 11 中谷歌也新增了 ADB 增量 APK 装置 性能,比方一个 APK 有 2GB,我下载完 50 MB 当前,就能够应用一些基本功能,残余的文件通过后盾流式传输,不过 Android 11 中的这个性能是面向 ADB 的。
尽管这个性能很赞,然而对签名计划带来了一些挑战,之前的计划都是基于所有文件进行校验的,于是推出 Android 第四代签名计划 v4。
v4 基于 APK 所有的字节计算出 Merkle Hash 树,并将 Merkle 树的根 Hash、盐值作为签名数据进行包完整性校验,v4 签名必须独自存在 .idsig 文件中,不会存在于 APK 文件中,所以 apk 文件中依然须要 v2 或者 v3 签名。
5. 向下兼容的签名计划
Android 中的签名计划是自上而下兼容的,如图:
对于 Android 11 来说,验证过程是这样的:
- 是否反对 v4,v4 验证完了再验证 v3 或者 v2
- v4 不通过,验证 v3
- v3 不通过,验证 v2
- v2 不通过,验证 v1
- v1 不通过,装置失败
对于 Android 9 来说,就得从 v3 计划开始验证的。
总结
读完这篇文章,置信你对 Android 签名计划有了根底的理解。
如果文章有不对的中央,评论区见~
参考文章:
《Android v1、v2、v3 签名详解》
《增量装置与安卓 V4 签名简介》
《官网文档》
本文由博客一文多发平台 OpenWrite 公布!