Android 的安装包签名方案到目前有3个版本,分别是:

  • 最初签名方案V1;
  • 为了提高验证速度和覆盖度在 7.0 引入的 V2;
  • 以及为了实现密钥轮转在 9.0 引入的 V3。

让我们分别了解一下这些签名的原理:


一、 V1 签名方案

1. 签名相关的文件

apk 本质是个 zip 文件,解压缩后,在 META-INFO 文件夹中可以看到有 MANIFEST.MFCERT.SFCERT.RSA 三个文件。这三个文件在签名时创建,在安装时用于验证签名。下面让我们看一下这三个文件各自的作用:

1.1 MANIFEST.MF文件

文件的作用: 记录 apk 中每一个文件对应的摘要信息,防止某个文件被篡改。

文件的内容: 打开 MANIFEST.MF 文件可以看到文件内容是这种格式:

Manifest-Version: 1.0
Built-By: Generated-by-ADT
Created-By: Android Gradle 2.3.1Name: res/drawable-hdpi-v4/tracepoint_tip.png
SHA1-Digest: UqNwQcd9oLGpVfILjkVOtNQmySA=Name: res/layout/activity_new_base_layout.xml
SHA1-Digest: Uw3jXiCR9Msf9C6P0Mjcmh2/A/E=...

前三行记录了基础信息,后面每一块都对应了 apk 中一个原始文件的数据摘要,摘要算法是 SHA-1。 在 MANIFEST.MF 文件没被篡改的情况下,可以用于保证 apk 中的其他文件不被篡改。 那怎么保证 MANIFEST.MF 文件本身不被篡改呢? 就是靠下面的 CERT.SF 文件了:


1.2 CERT.SF文件

文件的作用: 记录 MANIFEST.MF 文件的摘要,以及 MANIFEST.MF 中,每个数据块的摘要。防止 MANIFEST.MF 被篡改。

文件的内容: CERT.SF 的文件内容如下:

Signature-Version: 1.0
SHA1-Digest-Manifest: m4hofJv2im9b2HQo/h6VPKRnzqE=
Created-By: 1.0 (Android)Name: res/drawable-hdpi-v4/tracepoint_tip.png
SHA1-Digest: UqNwQcd9oLGpVfILjkVOtNQmySA=Name: res/layout/activity_new_base_layout.xml
SHA1-Digest: Uw3jXiCR9Msf9C6P0Mjcmh2/A/E=
...

第一行 Signature-Version 记录了签名版本; 第二行 SHA1-Digest-Manifest 记录了整个 MANIFEST.MF 文件的摘要;

后面每一块都是 MANIFEST.MF 中对应数据块的摘要; 例如,CERT.SF 中对应的这一段:

Name: res/drawable-hdpi-v4/tracepoint_tip.png
SHA1-Digest: UqNwQcd9oLGpVfILjkVOtNQmySA=

其中「UqNwQcd9oLGpVfILjkVOtNQmySA=」就是 MANIFEST.MF 中这一段的摘要(包含换行符):

Name: res/drawable-hdpi-v4/tracepoint_tip.png
SHA1-Digest: UqNwQcd9oLGpVfILjkVOtNQmySA=
rn

CERT.SF 如果没被篡改,就能用于验证清单文件 MANIFEST.MF 是否被篡改。但又怎么验证 CERT.SF 是否被篡改呢? 靠的就是签名文件 CERT.RSA 了:


1.3 CERT.RSA文件

文件的作用: 这个文件是为了验证 CERT.SF 文件有没有被篡改。

文件的内容: 它包含了 「对 CERT.SF 文件的签名」以及「包含公钥的开发者证书」。

如果不了解 证书和签名 是如何用于数据验证的,可以看《摘要、签名与数字证书都是什么?》


2. V1的签名机制

V1 签名的流程

签名的流程如下:

1. 计算每一个原始文件的 SHA-1 摘要,写入到 MANIFEST.MF 中;

2. 计算整个 MANIFEST.MF 文件的 SHA-1 摘要,写入到 CERT.SF 中;

3. 计算 MANIFEST.MF 中,每一块的 SHA-1 摘要,写入到 CERT.SF 中;

4. 计算整个 CERT.SF 文件的摘要,使用开发者私钥计算出摘要的签名;

5. 将签名和开发者证书(X.509)写入 CERT.RSA


3. V1签名是怎么校验的?

校验的流程如下:

1. 取出 CERT.RSA 中包含的开发者证书;

2. 通过系统的根证书(CA证书)验证这个开发者证书是否可信;

3. 如果开发者证书可信,用证书中的公钥解密 CERT.RSA 中包含的签名。

4. 计算 CERT.SF 的签名;

5. 对比 (3) 和 (4) 的签名是否一致;

6. 如果一致,用 CERT.SF 去校验 MANIFEST.MF 是否被修改;

7. 如果没有被修改,再用 MANIFEST.MF 中的每一块数据去校验每一个文件是否被修改。


4. V1签名如何防止篡改

假如攻击者修改了其中某一个文件,那么他必须修改 MANIFEST.MF 中对应文件的摘要,否则这个文件校验不通过; 接着还得修改 CERT.SF 中的摘要,否则摘要校验不过; 还得重新计算 CERT.SF 的签名,否则签名校验不通过; 但是计算签名需要私钥,私钥在开发者手中,攻击者没有私钥,所以无法签名。


5. V1签名存在的问题

校验速度慢:需要对 apk 中的每个文件都计算摘要并验证,如果文件很多,校验时间会很长。 完整性不够:V1 签名只会校验 Zip 文件中的部分文件,例如 META-INFO 文件夹就不会参与校验。


二、 V2 签名方案

V2 签名是在 Android7.0 之后引入的,它解决了 V1 签名校验时速度慢的问题,同时对完整性的校验扩展到整个安装包。

了解 V2 签名原理之前,我们先了解一下 Zip 文件:

1. Zip 文件

1.1 Zip 文件的格式和解析过程

zip 的文件格式
  1. 先从文件尾部查找 0x06054b50,确定 End Of Central Directory Record 区域的起始位置;
  2. 解析 EoCD 区域,并获得中央目录的起始位置;
  3. 根据起始位置,逐个解析文件。

从解析过程可以看出,如果在 「文件信息部分」 和 「中央目录部分」之间插入了其他数据,是不会影响 Zip 文件的解压缩的。


2. V2 签名数据块的格式

V2 签名时,会将 签名信息块 插入到 Zip 文件的「文件信息」和「中央目录」之间,如图:

「Apk Signing Block」的具体结构:

签名块的前8个字节记录了所有键值对数据块的大小。其后紧接着键值对数据块,数据块由一个个的键值对块组成。 每个键值对块的开始8字节记录了「键值对的ID」和「键值对的Value」的大小。接下来4字节是键值对的ID,后面跟着对应的值。 ID = 0x7109871a 的键值对块就是保存签名信息的地方。 键值对数据块的后面还有8个字节,也是用于记录「键值对块」的大小,它的值和最开始的8字节相同。 签名块的末尾是一个魔数,也就是‘APK Sig Block 42’的 ASCII 码。

下一篇文章我们会讲到如何在这里动态插入其他信息,例如渠道信息等。

签名信息的具体结构:


3. V2 摘要计算方式

V2 签名摘要的计算就不是按照文件计算的了,而是按照 1MB 为单位计算:

步骤: 1. 对原始apk文件的 文件信息部分、中央目录部分、EoCD部分,按照 1MB 大小分割为多个小块(Chunks); 2. 分别对每一个小块计算其摘要,类似于 V1 签名中的 MANIFEST.MF 文件; 3. 对(2)中所有摘要计算其摘要,类似于 V1 签名中的 CERT.SF 文件;

4. V2 签名的校验

Android 7.0 及以上在校验时,会先判断是否具有 V2 签名,如果有 V2 签名,会走 V2 签名的校验流程,不再验证V1签名了。

如何判断是否有V2签名? 根据Zip文件格式的规则,我们可以找到中央目录区的起始位置。 读取从起始位置开始往回的16个字节,判断这16个字节的值是否为 "Apk Sig Block 42",如果是,则对应上了魔数,说明有 V2 签名。后续就是解析 V2 签名块的流程了。

用公钥和签名对蓝色区域验证,验证通过后,用 「APK数据摘要集」对APK每一块做验证。


三、 V3 签名方案

V3 签名方案的签名块格式和V2完全一样,只是 V2 的签名块信息存放在 ID = 0x7109871a 的数据块中,而 V3 的签名信息存放在 ID = 0xf05368c0 的数据块中。

在这个新的数据块中,记录了旧的签名信息和新的签名信息,以密钥转轮的方案,做签名的替换和升级。这意味着我们可以更改 APK 的签名。

android怎样判断插入数据是否成功_Android 端 V1/V2/V3 签名的原理相关推荐

  1. android怎样判断插入数据是否成功_MySQL一个表的自增id用完了,背井大佬让我用这些姿势再往里插数据...

    点击上方"码之初"关注,···选择"设为星标" 与精品技术文章不期而遇 在之前有篇文章中,和大家探讨了在MySOL数据库中,一个表的自增id用完,再插入数据有什 ...

  2. android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本)

    android SQLite 批量插入数据慢的解决方案 (针对于不同的android api 版本) 参考文章: (1)android SQLite 批量插入数据慢的解决方案 (针对于不同的andro ...

  3. oracle 存储过程插入数据不成功

    oracle 存储过程插入数据不成功: 最大的一个原因是你定义的变量名和你表字段名相同!在定义的变量名前加个t_,问题就解决了!

  4. php插入成功数据不显示,PHP插入数据不成功,什么原因呢?

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //session_start(); $jobname=$_POST["jobname"]; $mane=$_POST["m ...

  5. android sqlite批量操作,Android: SQLite批量插入数据的最佳实践

    大家都知道,Android里数据库用的是SQLite.在实际开发过程中,我们有时候会遇到批量插入数据的场景.这篇文章给大家分享一个小技巧,让批量插入数据达到最快的目的. 首先,我先创建一个Table, ...

  6. android V1,V2,V3,V4签名详解

    前言 最近帮测试做了一点关于签名的需求,今天就和各位同学简单聊一聊关于签名的那些事儿. 如果问到 Android 为什么需要签名?大家都可能想到官网的解释: ❝ Android 系统要求所有 APK ...

  7. 数据库不同数据类型的字段插入数据能成功----将varchar类型数据插入到int中成功了。

    这种现象不仅仅在插入的时候会有,在数据的查询中也会出现,大体上归结与数据的类型不一致的问题. 这边笔者也是通过查询资料以后总结出来的,要是有哪边说的不对,还请指出!谢谢! 解释:数据库中应该是有一个数 ...

  8. Android 自动向上滚动,android – Recyclerview在插入数据时自动向上滚动

    我遇到了一个问题,当我将数据添加到数组列表然后将其添加到适配器之后,当我将其设置为recycleler视图适配器时,它会自动跳转到顶部我如何能够阻止它,就像我想在虚拟空间中添加数据一样我也尝试过使用 ...

  9. php 插入数据 不成功,thinkphp5连接oracle用insert插入数据失败

    春华秋衣 oracle主键log_id 不能自动递增有两个办法:1.使用oracle的自动增长序列创建序列 create sequence S_T_THINK_LOG increment by 1 / ...

最新文章

  1. 分布式事务之底层原理揭秘
  2. 服务器上的电脑登不上oracle,Oracle服务器改计算机名后报错之解决方法
  3. java -jar 指定端口_「Linux命令」-Java程序员需要掌握的10个命令
  4. 峰Redis学习(6)Redis 数据结构(sorted-set的操作)
  5. 如何将散乱的css代码规范化、格式化
  6. CSS3实现卡片翻转动画
  7. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-10.Springboot2.x用户登录拦截器开发实战...
  8. 怎么将PDF转换成Word?PDF转Word如何不乱码?
  9. 开发idea插件教程
  10. 看小伙是如何用python尽览我国植被覆盖率的沧海变化
  11. 【三角函数】和差化积、积化和差的公式及推导证明
  12. 任何矩阵都能变换成梯形阵的证明
  13. 制作MMORPG游戏需要储备哪些技术鲨鱼辣椒
  14. uber_您需要了解的有关Uber驾驶的知识
  15. spotlight搜索失效_如何在iPhone和iPad上自定义Spotlight搜索
  16. Fortunate Finds
  17. Ubuntu 下编写C程序
  18. 20181225股市复盘
  19. python 二项式分布学习
  20. requireJS define require

热门文章

  1. 等保2.0标准发布一周年,行业用户如何有效落实合规建设
  2. Json学习总结(6)——Fastjson远程代码执行漏洞
  3. Spring MVC学习总结(20)——SpringMVC传参总结
  4. Docker学习总结(33)——Docker环境下搭建 MySQL 主从复制
  5. python爬房源信息_用python爬取链家网的二手房信息
  6. php文章管理系统_PHP-小程序:(1)开发环境搭建
  7. 港铁将更换信号系统 或影响日间列车服务冀乘客谅解
  8. python sys.argv
  9. 基本排序(C语言版)
  10. Java 并发:第三部分 - 同步锁