您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

一文看懂Android签名v1、v2、v3、v4,竟然都v4了?

时间:2022-07-16 15:41:30  来源:  作者:闪念基因

本文作者: 九心,原文发布于: 九心说

前言

最近帮测试做了一点关于签名的需求,今天就和各位同学简单聊一聊关于签名的那些事儿。

如果问到 Android 为什么需要签名?大家都可能想到官网的解释:

Android 系统要求所有 APK 必须先使用证书进行数字签名,然后才能安装到设备上进行更新。

这是一个比较模糊的解释,简单来说,有了签名,就可以让 App 和开发者绑定。

毕竟,应用那么多,别的开发者也有可能盗用你的代码,这个时候,包名和你相同,代码和你相同,怎么区分你的 App 和这些人的 App 不是同一个呢?

这个时候数字签名就派上用场了。

1

签名基础

想要彻底了解签名知识,我们得了解以下知识:

  • 消息摘要

  • 数字签名

  • 加密

  • 数字证书

这一系列的知识各位可能在学习网络的时候或多或少的接触过。

我们简单的学习一下这些知识:

1. 消息摘要

消息摘要常常被被称为数字摘要或者数字指纹,定义如下:

在原来的数据基础上,经过一个单向的 Hash 计算,得到一个固定的 Hash 值,这就是消息摘要。

常见的摘要算法都有 MD5、SHA-1 和 SHA-256,特点如下:

1. 「 长度固定,与内容长度无关」:比如 MD5 是 128 位、SHA-1 是 160 位、SHA-256 是 256 位。

2. 「 看似随机,其实不随机」:同内容两次摘要得出的结果一致。

3. 「 单向」:只能从原数据得出摘要,不能从消息摘要得出原来的数据。

4. 「 优秀的摘要算法很难 Hash 碰撞」。

基于此,消息摘要常常会被用来检查内容的完整性。

比如我们下载起点读书,消息摘要的用法如下:

1. 计算摘要:App 会针对自己的文件信息计算出一个数字摘要比如 123**...**123。

2. 下载App。

3. 验证摘要:对下载的 App 再次计算摘要,比如得出的也是 123**...**123,和之前的数字摘要一对比,这就代表我从服务器下载的内容是完整的,可以正常使用。

当然,上面只涉及了摘要部分,其他过程,我们后面分析。

2. 加密算法

什么是加密?

百科是这么解释的:

将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。

所以啊,加密方法得到的密文是可以转变为明文的,像信息摘要算法比如 MD5 得出来的结果是不可逆的,所以面试官问你们什么是加密算法的时候,你可不能把 MD5 说进去!

加密算法分为两大类,「 对称加密」和「 非对称加密」。

2.1 对称加密

对称加密在加密和解密的时候使用的同一把钥匙:

图片来自《一文彻底搞懂加密、数字签名和数字证书!》

2.2 非对称加密

非对称加密是使用公钥/私钥中的公钥来加密明文,然后使用对应的私钥来解密密文的过程:

图片来自《一文彻底搞懂加密、数字签名和数字证书!》

简单对比一下对称加密和非对称机密:

  非对称加密 对称加密
速度
效率
安全性
常见算法 RSADH AESDESIDEA

2.3 使用场景

学过网络的同学应该都了解,在 Https 的传输过程中,客户端和服务端使用非对称加密生成对称加密的密钥,然后用对称加密传输网络中的数据。

比如我上大学那会儿,每个月的月尾我和我妈的对话是这样的:

对话

网络环境是开放的,万一这时,有一个黑客监听了我和我妈的对话,过程就变成了这样:

监听过程

在我发卡号的时候,黑客将我的卡号改成了他的卡号,于是我的生活费变成了他的生活费。

为了避免这种情况,于是我和我妈约定好了,每次发送前,使用对称加密对消息进行加密,接受消息的时候使用密钥解密,过程就变成了这样:

对称加密

中间人再也不能获取到消息了,看似一点问题都没有,但是我和老妈之间如何确定密钥呢?

密钥总要在互联网之间进行传输的,有传输就有被中间人截获的风险,一旦被截获,钱可就没了!

为了解决对称加密钥匙传输的问题,我和老妈用上了非对称加密,像这样:

非对称加密

即使这样,还是有问题存在:

1. 怎么才能确认我获得的公钥来自老妈?

2. 如何确定消息确实来自老妈?

解决这两个问题也很简单,一是数字签名,二就是数字证书。

3. 数字签名

数字签名的作用是为了消息的完整性。

在非对称加密的体系下,消息的发送过程是这样的,还是上面的例子:

数字签名

数字签名的过程是这样的:

1. 我发送消息前,利用 Hash 算法针对数据得出一个摘要。

2. 我使用老妈的公钥对摘要内容进行加密,连同对称加密的数据一起发送过去。

3. 老妈接收到消息后,先利用对称密钥对内容解密,再进行 Hash 计算得出摘要。

4. 老妈使用私钥将摘要内容解密,和再次计算得出的摘要作对比,一致就代表消息无误。

上面的这种场景其实有点不妥,数字签名一般用在证书上,协商好对称密钥以后一般不会进行消息完整性校验了,不过大伙只要了解数字签名要来校验消息完整性就好。

截止现在,还有最后一个问题,我无法确认获取的公钥确实来自老妈。

4. 数字证书

证书的作用很简单,证明公钥的身份。

就像在现实中,大家都是怎么证明自己的身份的?

没错,是身份证。你有没有发现,每张身份证,会有三种信息:

1. 自身的信息。

2. 置办身份证的派出所。

3. 有效期。

对应的数字证书也有很多内容:

1. CA:证书的颁发机构。

2. 证书的有效期。

3. 公钥。

4. 证书的授予对象。

CA 将这些内容利用 CA 的私钥进行签名,用户使用 CA 的公钥验签,从而证明公钥的身份。

常见的证书分为两种:

1. 签名证书:由 CA 机构颁发,绝大部分网站都采用的这种方式。

2. 自签名证书:由服务器自己颁发给自己。

重回之前的例子,老妈只需要将自己的签名证书发给我,我就可以获取她的公钥,之后就可以正常的通信。

2

Android签名机制

在 Android 中,也需要使用数字证书做数字签名,数字证书中公钥对应的私钥由开发者持有。

关于私钥和证书的生成方式,可以查看:

《Android官方文档》

https://developer.android.com/studio/publish/app-signing?hl=zh-cn#debug-mode

在 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需要生成的参数。

3

签名方案

目前 Android 支持以下四种应用签名方案:

1. v1方案:基于 JAR 签名。

2. v2方案:Android 7.0 引入,改动大。

3. v3方案:Android 9.0 引入,基于 v2 的升级。

4. v4方案:Android 11.0 引入,用来支持 ADB 增量 APK 安装。

1. v1方案

v1 是一个老生常谈的签名了,签名过程也很简单。

我们如果选中一个任意签名后的 apk 进行解压,会找到一个META-INF文件,这个文件里一般会有以 MF、SF 和 RSA 结尾的文件,如图:

这些文件在 v1 签名流程中是这样的:

v1流程

验证过程在 Apk 安装的过程中:

v1验证

整个过程清晰明了,但 v1 有两个问题:

第一个问题是签名校验慢,要针对 Apk 中所有的文件进行校验,这会拖累老设备的安装时间。

第二个问题是仅针对 ZIP 条目校验,META-INF文件不会计入校验过程。这样会导致即使我 Apk 已经签过名,工程师也可以移动条目顺序并重新压缩,也可以修改 META-INF文件下的内容,带来一些安全隐患,早期的多渠道打包就是在这里做的文章。

2. v2方案

v2 是 Android 签名方案的一大步,它解决了 v1 遗留的签名校验慢和完整性的问题。

我们先来看一下 v2 的组成部分:

签名前和签名后的 APK

v1 的组成部分其实就和 Before signing 那一块儿一样,v2 多了红色区域,我们称之为APK签名分块。

签名后的各个 APK 部分

从保护的内容来看,v1 仅保护内容1,v2 保护的区域有 1、3、4 和 2 的 signed data 区域,signed data 是 1、3 和 4 得出来的摘要等信息。

签名过程

就一个 App 而言,它可能有一个或者多个签名者,对于每个签名者而言,都会进行签名过程。

v2 没有对每个文件都进行计算,而是针对的所有字节。它将 1、3 和 4 区域都拆分成了大小为 1MB 的连续块,计算方式如下:

1. 每个小块都按:字节 0xa5 + 块字节长度 + 块内容 进行计算。

2. 每个1、3 和 4 块都按:字节 0xa5 + 块数 + 小块摘要 进行计算。

最后,将这些一个或者多个签名者的摘要、证书等信息都打包到 Apk 中。

v2流程

验签过程

v2 方案的 APK 验证过程是这样的:

1. 找到APK签名分块区域。

2. 每找到一个签名者,都会验证:签名算法、信息摘要、证书和公钥。

3. 所有的签名者都验证通过了,APK 验证才会通过。

3. v3方案

v3 方案建立在 v2 的基础上,目标是解决在更新过程中更改签名密钥的问题。

所以 APK 签名分块中 添加了两部分内容:

1. Proof-of-rotation: 一个存在替换的所有旧签名证书的链表,根节点是最旧的证书。

2. 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 中的签名方案是自上而下兼容的,如图:

APK 验证流程 v4

对于 Android 11 来说,验证过程是这样的:

1. 是否支持 v4,v4 验证完了再验证 v3 或者 v2

2. v4 不通过,验证 v3

3. v3 不通过,验证 v2

4. v2 不通过,验证 v1

5. v1 不通过,安装失败

对于 Android 9 来说,就得从 v3 方案开始验证的。

总结

读完这篇文章,相信你对 Android 签名方案有了基础的了解。

如果文章有不对的地方,评论区见~

参考文章:

《Android v1、v2、v3签名详解》

《增量安装与安卓V4签名简介》

《官方文档》

https://source.android.google.cn/security/apksigning?hl=zh-cn

最后推荐一下我做的网站,玩Android: wanandroid.com,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!

遵循最新安卓架构,做一个完美的玩Android App

超好的的包体积优化教程,真不仅仅是优化!

科技!让Native Crash 与ANR无处发泄!



Tags:Android   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Android 15 有望引入应用隔离功能,进一步提升系统安全性
IT之家 4 月 17 日消息,即将推出的 Android 15 系统可能引入一项全新功能:应用隔离。这一功能将更好地保护用户免受行为异常应用的侵害。Android 系统一直拥有强大的安全防护...【详细内容】
2024-04-17  Search: Android  点击:(8)  评论:(0)  加入收藏
Android 15 有望带来 NFC 无线充电支持,小型设备充电更方便
IT之家 4 月 16 日消息,说到无线充电,大多数人可能首先会想到 Qi 标准。Qi 无线充电已经存在很长一段时间了,并且广泛应用于我们日常使用的许多智能设备中。然而,许多小型电子设...【详细内容】
2024-04-16  Search: Android  点击:(5)  评论:(0)  加入收藏
Android Emulator黑屏怎么办 Android模拟器黑屏解决方法
Android Emulator黑屏问题困扰了非常多的玩家,Android Emulator作为一款安卓模拟器,可以让你在电脑上运行和浏览安卓应用程序,但是程序本身不是很稳定,很容易会出现黑屏,启动不了...【详细内容】
2024-03-04  Search: Android  点击:(46)  评论:(0)  加入收藏
Android 谷歌三件套:解锁谷歌生态!
大家是不是遇到这个情况?当我们需要下载一些国外的游戏或者软件的时候,需要在手机里面安装Google Play商店,然后通过Google Play商店下载国外软件!为了帮助大家使用上各种好用的...【详细内容】
2024-01-02  Search: Android  点击:(117)  评论:(0)  加入收藏
Android开发中常见的Hook技术有哪些?
Hook技术介绍Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事...【详细内容】
2023-12-25  Search: Android  点击:(92)  评论:(0)  加入收藏
在Android应用开发中使用NFC功能
NFC介绍NFC是指“近场通讯”(Near Field Communication),它是一种短距离无线通信技术,允许设备在非接触或极短距离内进行通信。NFC通常用于移动支付、门禁系统、智能标签和其他...【详细内容】
2023-12-22  Search: Android  点击:(104)  评论:(0)  加入收藏
关于Android图像Bitmap类,你要知道的一切
Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色...【详细内容】
2023-12-19  Search: Android  点击:(102)  评论:(0)  加入收藏
Android开发中如何进行单元测试?
单元测试介绍单元测试是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是函数或方法)是否按预期工作。单元测试通常由开发人员编写,旨在隔离和测试代码的特定部...【详细内容】
2023-12-11  Search: Android  点击:(170)  评论:(0)  加入收藏
我的手机我做主,如何为Android手机应用换图标?
作为一名Android用户,你是否曾经为自己的手机桌面感到单调而乏味?虽然Android系统的桌面定制性已经非常强大,但有时候我们还是希望能够在细节上做出一些改变,尤其是对于那些每天...【详细内容】
2023-12-10  Search: Android  点击:(62)  评论:(0)  加入收藏
了解Android系统架构中的HAL硬件抽象层
在Android系统中,HAL的存在使得不同厂商的硬件可以统一被上层的应用程序调用,从而提高了系统的兼容性和可移植性。HAL还可以帮助开发者更方便地开发应用程序,因为他们不需要为...【详细内容】
2023-12-06  Search: Android  点击:(214)  评论:(0)  加入收藏
▌简易百科推荐
Android Emulator黑屏怎么办 Android模拟器黑屏解决方法
Android Emulator黑屏问题困扰了非常多的玩家,Android Emulator作为一款安卓模拟器,可以让你在电脑上运行和浏览安卓应用程序,但是程序本身不是很稳定,很容易会出现黑屏,启动不了...【详细内容】
2024-03-04  18183游戏网    Tags:Android Emulator   点击:(46)  评论:(0)  加入收藏
Android开发中常见的Hook技术有哪些?
Hook技术介绍Hook技术是一种在软件开发中常见的技术,它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作,或者在特定的事...【详细内容】
2023-12-25  沐雨花飞蝶  微信公众号  Tags:Android   点击:(92)  评论:(0)  加入收藏
在Android应用开发中使用NFC功能
NFC介绍NFC是指“近场通讯”(Near Field Communication),它是一种短距离无线通信技术,允许设备在非接触或极短距离内进行通信。NFC通常用于移动支付、门禁系统、智能标签和其他...【详细内容】
2023-12-22  沐雨花飞蝶  微信公众号  Tags:Android   点击:(104)  评论:(0)  加入收藏
关于Android图像Bitmap类,你要知道的一切
Bitmap介绍Bitmap是一种图像文件格式,它由像素阵列组成,每个像素都有自己的颜色信息。在计算机图形学中,Bitmap图像可以被描述为一个二维的矩阵,其中每个元素代表一个像素的颜色...【详细内容】
2023-12-19  沐雨花飞蝶  微信公众号  Tags:Android   点击:(102)  评论:(0)  加入收藏
Android开发中如何进行单元测试?
单元测试介绍单元测试是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是函数或方法)是否按预期工作。单元测试通常由开发人员编写,旨在隔离和测试代码的特定部...【详细内容】
2023-12-11  沐雨花飞蝶  微信公众号  Tags:Android   点击:(170)  评论:(0)  加入收藏
一篇聊聊Jetpack Room实现数据存储持久性
Room介绍Room 是 Android Jetpack 组件库中的一部分,它是用于在 Android 应用中进行本地数据库访问和管理的库。Room 提供了一个抽象层,使开发者能够更轻松地访问 SQLite 数据...【详细内容】
2023-12-08  沐雨花飞蝶  微信公众号  Tags:Jetpack   点击:(149)  评论:(0)  加入收藏
了解Android系统架构中的HAL硬件抽象层
在Android系统中,HAL的存在使得不同厂商的硬件可以统一被上层的应用程序调用,从而提高了系统的兼容性和可移植性。HAL还可以帮助开发者更方便地开发应用程序,因为他们不需要为...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:Android   点击:(214)  评论:(0)  加入收藏
我们一起聊聊 IntentService 与 Service 的区别?
Service介绍Service组件是Android应用开发中的四大组件之一,用于在后台执行长时间运行的操作或处理远程请求。它可以在没有用户界面的情况下执行任务,并且可以与其他应用组件...【详细内容】
2023-12-06  沐雨花飞蝶  微信公众号  Tags:IntentService   点击:(179)  评论:(0)  加入收藏
Android数据对象序列化原理与应用
序列化与反序列化「序列化」是将对象转换为可以存储或传输的格式的过程。在计算机科学中,对象通常是指内存中的数据结构,如数组、列表、字典等。通过序列化,可以将这些对象转换...【详细内容】
2023-11-14  沐雨花飞蝶  微信公众号  Tags:Android   点击:(280)  评论:(0)  加入收藏
你了解Android中的SELinux吗?
SELinux介绍SELinux(Security-Enhanced Linux)是一种安全增强的Linux操作系统,它通过强制访问控制(MAC)机制来提供更高级别的系统安全保护。相比于传统的Linux访问控制机制(DAC),SEL...【详细内容】
2023-11-09  沐雨花飞蝶  微信公众号  Tags:Android   点击:(272)  评论:(0)  加入收藏
站内最新
站内热门
站内头条