Apk结构,签名原理

2020-04-26  本文已影响0人  杨殿生

Apk解压后的文件结构

Apk结构.png

这里主要关注未签名和签名的apk的区别
未签名的apk是没有MEAT-INF文件夹的,只有签名的apk才有这个文件夹。分别来看一下这个文件夹下的文件的含义

MANIFEST.MF

校验应用完整性的文件,里面的结构是apk中每个文件生成的摘要

CERT.SF

签名文件,是对MANIFEST.MF进行加密的(非对称加密)

CERT.RSA

公匙,用于解密使用

Android签名

签名是什么?
签名就是摘要和非对称加密的产物

V1签名

文件结构
.MF(摘要文件,对apk中的资源名和资源进行摘要)
.SF(二次摘要文件,存储资源名和.MF中的条目进行摘要)
.RSA (公钥以及签名文件,对.SF进行的摘要签名加密,含有证书指纹)

不同的keystore进行签名,.MF和.SF生成的文件是一致的,不同的是.RSA文件。.MF和.SF保证完整性,.RSA保证来源

如何保证apk文件不可修改

使用.SF .MF .RSA保证apk不被更改

保证信息完整性原理

签名的过程

无论是debug还是release包都是要有签名文件的,我们在生成release包的时候也是先生成我们自己的私匙
1,为我们apk中文件都生成校验唯一性的hash值,生成MAINIFEST.MF文件,MAINIFEST.MF包含所有文件的摘要
2,对MANIFEST.MF进行二次摘要生成CERT.SF,CERT.SF包含所有文件的摘要,但比MAINIFEST.MF多了,MAINIFEST.MF的总体摘要,和MAINIFEST.MF生成所有文件摘要的摘要, 防止MAINIFEST.MF被篡改
3,.RSA包含了签名者的证书信息,以及对CERT.SF文件的签名

验证过程

1,首先校验cert.sf文件的签名
计算CERT.SF文件的摘要,与通过签名者公钥解密签名得到的摘要进行对比,如果一致则进入下一步;
2,校验MAINIFEST.MF文件的完整性
计算MAINIFEST.MF文件的摘要,与CERT.SF主属性中记录的摘要进行对比,如一致则逐一校验MF文件各个条目的完整性;
3,校验apk中每个文件的完整性
逐一计算apk中每个文件(META-INF目录除外)的摘要,与MF中的记录进行对比,如全部一致,刚校验通过;
4,校验签名的一致性
如果是升级安装,还需校验证书签名是否与已安装app一致。

以上步骤需要全部通过才算签名校验通过,任何一步失败都将导致校验失败。这个过程能保证apk不可被篡改吗?我们来看看篡改apk内容会发生什么:
篡改apk内容
校验apk中每个文件的完整性时失败;如果是添加新文件,因为此文件的hash值在.mf和.sf中无记录,同样校验失败;
篡改apk内容,同时篡改manifest.mf文件相应的摘要
校验manifest.mf文件的摘要会失败;
篡改apk内容,同时篡改manifest.mf文件相应的摘要,以及cert.sf文件的内容
校验cert.sf文件的签名会失败;
把apk内容和签名信息一同全部篡改
这相当于对apk进行了重新签名,在此apk没有安装到系统中的情况下,是可以正常安装的,这相当于是一个新的app;但如果进行覆盖安装,则证书不一证,安装失败。
从这里可以看出只要篡改了apk中的任何内容,都会使得签名校验失败。

为什么要替换V2签名

1,签名校验速度慢
校验过程中需要对apk中所有文件进行摘要计算,在apk资源很多、性能较差的机器上签名校验会花费较长时间,导致安装速度慢;
2,完整性保障不够
META-INF目录用来存放签名,自然此目录本身是不计入签名校验过程的,可以随意在这个目录中添加文件,比如一些快速批量打包方案就选择在这个目录中添加渠道文件。

重新签名

从上面的过程来看,我们可以把市场上的apk下载下来,删除加密文件夹下的内容,然后重新为apk签名

V2签名(7.0 N)

如何保证apk文件不可修改?
增加了APK签名分块内,签名和签名者身份信息会存储在APK签名方案v2分块中,保证整个APK文件不可修改


V2签名后的文件结构

验证过程
v1是针对单个文件校验,v2签名不针对单个文件校验了,而是针对APK进行校验,将APK分成1M的块,对每个块计算值摘要,之后针对所有摘要进行摘要,再利用摘要进行签名。
也就是说,V2摘要签名分两级,第一级是对APK文件的1、3 、4 部分进行摘要,第二级是对第一级的摘要集合进行摘要,然后利用秘钥进行签名。安装的时候,块摘要可以并行处理,这样可以提高校验速度。

v2签名过程

V3签名(9.0 P)

Android 9.0 中引入了新的签名方式,它的格式大体和 V2 类似,在 V2 插入的签名块(Apk Signature Block V2)中,又添加了一个新快(Attr块)。

在这个新块中,会记录我们之前的签名信息以及新的签名信息,以密钥转轮的方案,来做签名的替换和升级。这意味着,只要旧签名证书在手,我们就可以通过它在新的 APK 文件中,更改签名。

V3 签名新增的新块(attr)存储了所有的签名信息,由更小的 Level 块,以链表的形式存储。

其中每个节点都包含用于为之前版本的应用签名的签名证书,最旧的签名证书对应根节点,系统会让每个节点中的证书为列表中下一个证书签名,从而为每个新密钥提供证据来证明它应该像旧密钥一样可信。

这个过程有点类似 CA 证书的证明过程,已安装的 App 的旧签名,确保覆盖安装的 APK 的新签名正确,将信任传递下去。

Apk签名校验

7.0以上的手机优先检测V2签名,如果V2签名不存在,再校验V1签名,对于7.0以下的手机,不存在V2签名校验机制,只会校验V1,所以,如果你的App的miniSdkVersion<24(N),那么你的签名方式必须内含V1签名:


v1、v2签名共存校验过程

参考
https://juejin.im/post/5cd239386fb9a0320f7dfcbe
https://blog.csdn.net/weixin_34279579/article/details/91470451
APK签名机制之——JAR签名机制详解
APK签名机制原理详解
APK签名机制之——V2签名机制详解

上一篇下一篇

猜你喜欢

热点阅读