一、简介

​由于频繁的更新迭代,移动终端上的大型应用程序越来越普遍。因此,从应用商店里下载大型应用安装包将无可避免的耗费大量时间,这已经成为移动终端用户的一大痛点。对于应用开发者而言,也需要改变现有的整包安装方案以满足用户需求。

在传统的应用安装方案中,开发者通过ADB(Android Debug Bridge)以有线或无线的方式与终端用户连接,或者用户从软件商店直接下载,然而该方案需要用户等待完整的安装包传输结束后才能启动安装,在这期间产生了不良的用户体验。

增量安装技术是一种流式的安装方案:一旦安装包的核心文件传输完成便可启动应用。流式安装意味着允许优先传输核心数据以启动应用,并在后台流式传输剩余数据。

对于APK而言,其核心数据包括可执行文件和重要的资源文件等。在数据传输开始前,ADB筛选出安装包的核心文件优先传输,一旦移动设备接收到启动应用所需的核心数据块后,该应用程序便可在虚拟文件系统上启动。

在Android 11中,Google在内核中实现了增量文件系统用于对增量安装的支持。(详见https://source.android.com/devices/architecture/kernel/incfs)

这使得Android os可以通过ADB流式传输APK。同时,Android 11为了适应增量安装,添加了新的V4签名方案。

此方案不改变前代签名方案而是创建一种新的签名:基于APK所有字节数据计算出Merkle哈希树,并将Merkle树的根哈希、盐值作为签名数据进行包完整性验证。新的签名数据保存在.idsig文件中并且在进行增量安装前必须为APK创建对应的V4签名文件。

二、增量安装


上图所示为增量安装的基本框架[1]。

ADB筛选出需要优先传输的文件,并通过增量文件流传递数据,同时在传输过程中创建传输日志并提供给开发者。

移动设备上的增量文件系统内核模块用于在操作系统中创建增量服务。增量服务接收来自ADB的增量安装请求,通知增量文件系统内核模块和包管理器(Package Manager)启动增量安装并追踪应用程序的安装过程。

接收到增量安装请求后,增量文件系统内核模块接收来自ADB的APK核心数据并放在增量文件系统内。

增量文件系统是运行在设备文件系统上的虚拟文件系统,它在接收到APK的核心数据文件后为整包分配空间并创建APK包的虚拟文件进行增量安装。

核心数据安装完毕后便可在设备上显示应用图标和应用所在目录。在用户启动应用后,ADB将在后台继续传输剩余的APK包数据。


上图所示为ADB优先选择的APK核心文件。ADB以增量的方式将APK数据传输给移动设备。预先传输的数据可以让APK提前启动。ADB追踪正在传输的数据并创建日志文件并提供给应用开发者。

三、Merkle树

Android V4签名方案的签名和验证是基于Merkle树进行。

Merkle树的设计之初是为了解决单一Lamport密钥不能签署多条信息及大信息量下公钥过长的问题[2]。

Merkle树本质上是将一系列Lamport公钥组合在一起,并用哈希函数计算出一个统一的公钥,这个公钥便是Merkle树的根哈希。

下面介绍利用Merkle树的生成并验证签名的过程。

对于下图的Merkle树:

  • 数据块1~数据块4有各自的密钥对(Xi,Yi),

  • Merkle树的叶子节点是对每个数据块的公钥计算的哈希值:hi=H(Yi)。

  • 非叶子节点的值是通过合并其子节点的值并计算哈希得到的。

以节点a1,0的计算为例,a1,0=H(a0,0||a0,1)。

依此类推,便可以计算出根节点哈希值并建立Merkle树,将根节点值作为公钥用于验证签名。

数块的签名包括加密该数据块的密钥以及该密钥的验证路径,其中验证路径是从叶子节点到根节点路径上的所有节点的兄弟节点。

Merkle树验证签名需要首先验证数据块的一次性签名,再验证该公钥的正确性。

以数据块1为例,首先验证密钥对(X0,Y0)是否正确匹配;

若是则验证Y0的正确性,根据a0,0的验证路径和根哈希进行验证。

节点a[0,0]的验证路径包括a[0,1]和a[1,1]。

通过a[0,0]与a[0,1]可计算出a[1,0],a[1,0]与a[1,1]可计算出根节点a[2,0],与Merkle树的公钥进行对比,若一致接收签名。

四、V4签名

V4签名基于APK字节计算Merkle树用于文件验证。

V4签名以如下数据结构保存在.idsig文件内,其中包括了用于验证签名的根哈希。

struct V4Signature {int32 version; // only version 2 is supported as of now
sized_bytes<int32> hashing_info;
sized_bytes<int32> signing_info;
sized_bytes<int32> merkle_tree;  // 可选择是否保存完整merkle树
};

其中sized_bytes的结构如下:

template <class SizeT>
struct sized_bytes {SizeT size;
byte bytes[size];
};

hashing_info 保存着哈希树的相关信息:哈希算法(SHA256)、数据块大小(4KB),盐值、根哈希。hashing_info的定义如下:

public static class HashingInfo {public final int hashAlgorithm;
public final byte log2BlockSize;
public final byte[] salt;
public final byte[] rawRootHash;
......
};

signing_info 保存用于验证签名的参数:数据摘要、签名数据、公钥、证书等。signing_info的定义如下:

public static class SigningInfo {public final byte[] apkDigest;
public final byte[] certificate;
public final byte[] additionalData;
public final byte[] publicKey;
public final int signatureAlgorithmId;
public final byte[] signature;
};

下面介绍如何生成V4签名。

首先以自底向上的方式生成Merkle树,如下图所示:

我们首先将APK的源数据划分为多个4KB的数据块,如果源文件最后部分不足4KB,则进行零填充来凑足4KB;

然后对这些4KB的数据块进行SHA256计算得到32B的哈希值,这部分哈希值就组成了Merkle树的第一层。

对于Merkle树的第二层,需要将第一层的进行组合,组合方式是依次将第一层的128个哈希值组合成4KB的数据块,如不足4KB则进行零填充,最后对这些4KB块进行SHA256计算得到Merkle树的第二层。

后面的部分以此类推,直到计算出Merkle数的根哈希。生成的哈希树以V4Signature的结构保存在.idsig文件内。

由根哈希计算出Hashinfo结构,根据Hashinfo和APK摘要生成V4签名。

当ADB请求增量安装时,PMS从.idsig文件中获取原生签名封装在V4Signature对象中。进行验证时,则从V4Signature获得签名数据和公钥,验证的过程与上一代签名方案类似。

五、总结

本文以增量安装和安卓V4签名方案为切入点,主要介绍了增量安装技术的应用框架以及V4签名方案的理论依据。

综上所述,增量安装是一种允许应用快速启动的流式安装技术,而为了支持增量安装而设计的V4签名则是一种具有Merkle树结构的签名。

在可预见的未来,增量安装和V4签名都将具有更广泛的应用场景。

Android AAB增量安装相关推荐

  1. bundletool工具使用(Android aab包安装)-Google play上架

    如果对"哆啦安全"感兴趣的可以扫二维码关注微信公众号,该公众号每天都会持续更新干货文章! APK再见了,Android正式宣布全新APP安装格式AAB https://github ...

  2. Android aab的打包、调试、安装

    一.前言 Google Play在今年3月发出了一个 Google Play新政策通知,即在今年8月后新应用必须以 API 级别 30 (Android 11) 为目标平台,并使用 Android A ...

  3. Android APP 增量更新demo

    随着现在手机硬件不断的提升,分辨率提高手机的安装包也是越来越大了.当年NOKIA,MOTO时代,一个手机APP如果有1MB那都是算大的,2MB已经不得了了.虽然网络.存储都已经大大提升,但是流量还不至 ...

  4. Android的增量更新

    Android的增量更新 随着现在移动端的不断普及,移动端逻辑越来越复杂,对移动端APP的要求也越来越高,所以对于一个没有用户的量APP,最重要的是用户.而一个对于一个有用户量的APP来说,最重要的是 ...

  5. 安卓aab包安装方式

    一.aab包简介 Google Play商店从 2021 年 8 月起,新应用发布需要使用Android App Bundle 才能在 Google Play中发布. Android App Bund ...

  6. 采用 bsdiff 开源库 Android 的增量更新,差分更新 服务器端客户端

    Incremental-update-master 项目地址: ccj659/Incremental-update-master 简介:采用 bsdiff 开源库 Android 的增量更新,差分更新 ...

  7. Android 探索增量升级

    一.介绍 Android 的增量升级,不同热修复和热更新,它只是通过和老的 apk 对比,识别出与新 apk 之间的二进制差异,从而生成的补丁包(差量包): 这样的好处在于,不用全部下载所有的文件,比 ...

  8. Android测试包安装方式汇总

    背景:作为一名测试,尤其是移动端测试,掌握app的安装方式是必备的基本技能,因此将Android测试包不同格式不同方式的安装方式进行一个总结分享​,仅供大家学习参考. 一.设备调试准备 1.设备打开开 ...

  9. Windows Android SDK下载安装,配置,异常问题解决教程

    Windows Android SDK下载安装,配置,异常问题解决教程 参考文章: (1)Windows Android SDK下载安装,配置,异常问题解决教程 (2)https://www.cnbl ...

  10. android linux应用安装位置,Android中App安装位置详解

    Android应用可以安装在本机自带存储,同时也可以安装到外部存储(SD卡).自从API 8后也就是Android2.2后,我们能使APK安装到外部存储上.这是一个可选的特性,在工程的manifest ...

最新文章

  1. python读取整个txt文件-Python读写txt文本文件
  2. JAVA命令运行cmd命令得到的结果乱码Runtime.getRuntime().exec();
  3. java调用存储过程sqlserver_Java调用SqlServer存储过程怎么实现 | 学步园
  4. mysql平台workb_MySQL 总结
  5. opencv 创建图像_非艺术家的图像创建(OpenCV项目演练)
  6. 4个常用的awk统计命令
  7. Mac Ubuntu ----端口被占用
  8. tornado学习笔记day07-同步与异步
  9. mysql 查看锁_别吵吵,分布式锁也是锁
  10. settimeout需要清除吗_前端20个真正灵魂拷问,前端初级到中级你还需要这个!
  11. mysql数据库备份注意,Tips: MySQL数据库使用mysqldump备份恢复时的注意事项
  12. Arcgis 重装 的 license 问题
  13. html中文字放在图片下边,css图片下边怎么加字
  14. Rails PayPal 支付对接
  15. java开发手机app教程,看完必懂
  16. 瑞幸的野望,小鹿茶的突袭
  17. 磁性微型机器人通过结肠翻筋斗以输送药物
  18. 红外夜视摄像头 小方智能摄像头使用手记
  19. java实现一元多项式减法_一元多项式 加法 减法 乘法
  20. 近视手术能不能做?怎么做?丁香医生告诉你

热门文章

  1. 快速安装rubyinstaller-devkit
  2. 近期流行手机病毒“手机骷髅”解决方案
  3. RecyclerView 实现多种布局(上半部Gridview样式,下半部Listview样式)以及多种数据类型实现不同布局
  4. F5 对接 Consul 实现服务发现和服务注册实践
  5. Android源码刷机步骤
  6. ACTIVEX控件debug版本在Win7下注册失败的处理方法
  7. “管家婆”软件用于维修管理 (转)
  8. Discuz搜索模块解析
  9. Padavan(老毛子)脚本自动切换网关和 DNS 服务器
  10. C#利用vbs控制3D Stereoscopic Player播放器