android7.0新签名机制

一般APP的签名验证有3种:本地验证、网络验证、本地验证+网络验证,其中本地验证也分Java层和Native层验证。

下面再简单叙述一下Apk安装过程中的验证步骤,其实就是和生成签名文件的步骤类似:
1. 首先检验Apk中的所有文件的数字编码和MANIFEST.MF中的数字编码一致;
2. 验证CERT.SF文件的签名信息和CERT.RSA中的内容是否一致;
3. MANIFEST.MF整个文件签名在CERT.SF文件中头属性中的值是否匹配以及验证MANIFEST.MF文件中的各个属性块的签名在CERT.SF文件中是否匹配。

Apk修改后缀名压缩文件解压

MANIFEST.MF:
这个文件保存的是每一个文件对应的一个唯一的值。MANIIFEST.MF文件的功能就如刚才说的一样,在对APK签名的时候,首先会对每一个文件进行数字编码,生成一个唯一的SHA1的值,不同的文件内容不一样所对应的SHA1的值也是不同的,所以如果有人篡改了文件内容,那么相应的SHA1的值也会发生变化。在对APK进行签名的时候检查自己的每一个文件,并生成对应的SHA1值,把这些内容都保存在一个新建的MANIFEST.MF文件中,并把这个文件放到META-INF目录下,就完成了第一个签名文件的生成。

CERT.SF:
在生成了一个MANIFEST.MF文件之后,就能记录下我们每一个文件的唯一值,从而保证文件不被篡改,这样虽然保证了MANIFEST中记录文件的安全,但却无法保证自身的安全,别人照样可以修改原有文件之后生成对应的SHA1值然后再修改MANIFEST文件,所以我们还要对MANIFEST进行加固,从而保证安全性。在进行完第一个文件生成后,签名工具开始生成第二个文件了,这个文件就是CERT.RSA。在这个步骤里,对上一步生成的文件继续进行一次数字编码,把结果保存在这个新生成了CERT.RSA文件的头部,在继续对MANIFEST.MF文件中各个属性块做一次数字编码,存到到CERT.SF文件的一个属性块中。

CERT.RSA:(二进制)
这个文件都是二进制的,生成完CERT.SF文件之后,我们用私钥对CERT.SF进行加密计算得出签名,将得到的签名和公钥的数字证书的信息一起保存到CERT.RSA中,整个签名过程就结束了。

从上面的过程中,可以很明显的发现一个问题,在这个过程中从来就没有对META-INF里的任何文件进行数字编码和加密,因为这个文件夹是签名时生成的,在生成第一个文件MANIFEST.MF时并没有对这个文件夹里的任何文件进行数字编码,因为这个文件夹一定是空的,第二个文件是基于第一个文件生成的,第三个文件又是基于第二个生成的,所以整个过程中,这个META-INF文件夹几乎是在控制范围之外的。我们可以在里面添加一些文件从而躲过签名这个过程。这就是美团多渠道包方案的突破口。

美团多渠道包方案的原理:
通过前面打包过程的了解,可以知道想快速打多渠道包,就得跳过打包的阶段直接想办法对Apk文件进行修改,但这得挑战Android的签名校验规则了,不过正好,通过刚才我们对签名过程的分析,我们发现可以在META-INF文件夹里随意添加文件从而躲过签名规则的检查,这时候新方案就孕育而生了,在打包生成了一个没有渠道的Apk文件后,我们copy这个Apk并在在META-INF里添加一个文件,然后通过文件名来确定渠道号,不同的Apk里就在META-INF里添加不同的渠道名文件,即可确定不同的渠道了,之后要做的就是在我们需要渠道参数的时候直接去这个文件里拿就行了,完美的跳过了打包这个过程。那么这种方案的耗时呢?仅仅就是基于一个Apk文件的基础上复制并插入一个文件而已,这样的动作在高配的电脑里一分钟可以做900次。所以,这时候打一个渠道包要4分钟,打100个渠道包也只要四分钟加一个小零头,当然,这还不是极限,如果有900个渠道的话,一个个渠道包打包需要900x4分钟,美团方案只要5分钟,提高了好几百倍的效率,可以说美团方案在老签名下是非常完美的。

新签名方式
新的签名方式是根据zip文件结构来进行签名的,Apk文件本质上就是一个.zip文件。

Zip文件格式:(http://blog.csdn.net/a200710716/article/details/51644421

[local file header + file data + data descriptor]{1,n} + central directory + end of central directory record 即 [文件头+文件数据+数据描述符]{此处可重复n次}+核心目录+目录结束标识;
当压缩包中有多个文件时,就会有多个[文件头+文件数据+数据描述符]。如下图所示。

再看看End of Central Directory的作用,它记录了Central Directory相对于头部的偏移位置,再看看我们的新签名数据Apk Signing Block是放在Contents of ZIP entries和Central Directory之间的,它是根据未签名的ZIP文件三个模块的所有内容进行编码签名后产生的一个唯一的数据,可以按照前面说的数字编码来理解,这三块任何内容发生改变后所产生的这块的数据都是不一致的,所以在签名之后无法对Apk的任何内容进行修改,不过我们前面也没修改过Apk签名之外的内容,所以这个时候是不是可以考虑修改Apk Signing Block这块内容呢,我们在后面再追加一个小尾巴。显然这个方法也不行了,前面说过最后有一个叫End of Central Direcotry的部分,记录着Central Direcotry相对与ZIP文件起始位置的偏移,正好APK Signing Block位于Central Direcotry前面,如果改变APK Signing Block的长度那么Central Direcotry相对于头部的偏移就改变了,内容就会和Endof Central Directory里记录的不一样,整个Apk包就被破坏了。那么是不是可以修改这个偏移呢,显然不行,修改过这个偏移之后Apk Signing Block也会变,然后只有拥有签名文件的开发者才能得到对的APK Signing Block数据,想要篡改这个的人只能望洋兴叹了。这就是新签名机制的作用原理。
感觉这样每段之间形成了相互关联,产生循环验证、相互校验的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值