APK Signature Scheme v2学习
zip
想了解APK Signature Scheme v2,就必须简单了解一下zip格式,维基百科wiki https://en.wikipedia.org/wiki/Zip_(file_format)
对于zip格式,其简单的数据结构如下
[Local file header +filedata + data descriptor]{1,n} + central directory +endofcentral directoryrecord
即[文件头+文件数据+数据描述符]{此处可重复n次}+核心目录+目录结束标识
核心目录决定zip中每个文件或目录的名称,以及关于条目的其他元数据以及到ZIP文件的偏移量,指向实际条目数据。这允许相对快速地读取zip的文件列表,因为不必读取整个zip查看文件的列表。 只有核心目录中存在的文件或者目录才是有效的。
![](https://img.haomeiwen.com/i531277/23f4714b1f1c971a.png)
ZIP文件通过读取核心目录结束标示来进行文件的追加zip,可以只操作核心目录进行删除操作。中央目录中的文件条目的顺序不必与归档中的文件条目的顺序一致。
ZIP格式使用特定的4字节“签名”来表示文件中的各种结构。每个文件条目由特定签名标记。中央目录记录的结束用其特定签名指示,并且中央目录中的每个条目以4字节的中心文件头部签名开始。
大多数签名以短整数0x4b50结尾,以小端顺序存储。作为ASCII字符串查看,这是“PK”,发明人Phil Katz的缩写。因此,当在文本编辑器中查看.ZIP文件时,文件的前两个字节通常是“PK”。
mac可以通过工具 Hex_Fiend可以更好的理解zip的格式。下面简单讲一个例子
![](https://img.haomeiwen.com/i531277/d07fade63c8caa10.png)
阅读ZIP的文件格式,我们知道目录结束可以通过目录结束标示得到核心目录的偏移位置。目录结束标示以504B0506开始,第16位记录核心目录的偏移量E2020000,也就是738,在编辑器738位置是504B0102,也就是Central directory file header的位置。
APK Signature Scheme v2
ndroid 7.0(Nougat)引入一项新的应用签名方案APK Signature Scheme v2,它是一个对全文件进行签名的方案,能提供更快的应用安装时间、对未授权APK文件的更改提供更多保护,在默认情况下,Android Gradle 2.2.0插件会使用APK Signature Scheme v2和传统签名方案来签署你的应用。
新的签名方案会在ZIP文件格式的Central Directory区块所在文件位置的前面添加一个APK Signing Block区块。结构如下
![](https://img.haomeiwen.com/i531277/809a837cb5a407a4.png)
签名信息回被保存在区块2中。
![](https://img.haomeiwen.com/i531277/85ef7371e8479397.png)
APK Signature Scheme v2提供更多保护是指除了区块2,在签名之后任意其他区块的更改都无法通过签名验证。v1 中仅验证未解压的文件内容,可以在签名后进行内容的修改,比如在apk META-INF路径下插入渠道文件。
更快的安装时间是指Apk安装时的签名验证耗时。
APK Signing Block 数据结构
size of blockin bytes (excluding this field) (uint64)
Sequence of uint64-length-prefixed ID-value pairs:
ID(uint32)
value(variable-length: length of the pair - 4 bytes)
size of blockin bytes—same as the very first field (uint64)
magic“APK Sig Block 42” (16 bytes)
block中可以存储多对ID-value pairs,我们需要知道每一对ID-value pairs的长度,才可以计算出下一组ID-value pairs的offset,关于长度的信息存储在value中:
value = (4b的长度标识+value真实数据)
在这个value的真实数据中可能就存在签名信息
关于签名数据的数据结构其实和上面类似,具体可以看看文档
apk签名和验证工具
有了上面的知识我们就可以开始看代码了
https://android.googlesource.com/platform/tools/apksig/
代码也能够生成jar文件,进行apk签名和验证签名
walle
一个新的渠道包大包方式,通过插入额外的ID-value pairs来存储渠道信息。
https://github.com/Meituan-Dianping/walle
参考
http://blog.csdn.net/a200710716/article/details/51644421
https://en.wikipedia.org/wiki/Zip_(file_format)
https://android.googlesource.com/platform/tools/apksig/
https://github.com/Meituan-Dianping/walle