通过前一篇Apk签名机制之——JAR签名机制详解的分析我们知道,JAR签名需要对apk内所有文件进行hash校验,当资源较多时签名验证速度较慢。为了加快验证速度并加强完整性保证,Andorid在7.0引入一种全文件签名方案V2。下面来看V2方案的具体设计原理。
1. V2签名设计思想
在了解V2签名结构前,先来了解下zip(apk)文件的结构。
1.1 ZIP文件结构
zip包结构
zip文件分为3部分:
数据区
此区块包含了zip中所有文件的记录,是一个列表,每条记录包含:文件名、压缩前后size、压缩后的数据等;
中央目录
存放目录信息,也是一个列表,每条记录包含:文件名、压缩前后size、本地文件头的起始偏移量等。通过本地文件头的起始偏移量即可找到压缩后的数据;
中央目录结尾记录
标识中央目录结尾,包含:中央目录条目数、size、起始偏移量、zip文件注释内容等。
通过中央目录起始偏移量和size即可定位到中央目录,再遍历中央目录条目,根据本地文件头的起始偏移量即可在数据区中找到相应的压缩数据。
1.2 V2签名原理
在Apk签名机制之——JAR签名机制详解中我们已经知道,JAR签名是在apk文件中添加META-INF目录,即需要修改数据区、中央目录,因为添加文件后会导致中央目录大小和偏移量发生变化,还需要修改中央目录结尾记录。V2方案为加强数据完整性保证,不在数据区和中央目录中插入数据,选择在 数据区和中央目录 之间插入一个APK签名分块,从而保证了原始zip(apk)数据的完整性。具体如下所示:
v2签名前后差异
v2 签名块负责保护第 1、3、4 部分的完整性,以及第 2 部分包含的APK 签名方案 v2分块中的signed data分块的完整性。
1.3 如何定位 APK签名方案V2分块?