APK签名

打包时可以看到Android支持两种签名方式:
APK签名_第1张图片

V1(Jar Signature):

JAR签名机制:
JAR签名对对jar包进行签名的一种机制,由于jar包apk本质上都是zip包,所以可以应用到对apk的签名。
APK文件中有一个META-INF目录,该目录中有3个文件,分别是CERT.RSA ,CERT.SF ,MANIFEST.MF,与签名相关

1.MANIFEST.MF内容:
APK中每个文件和它们的摘要(SHA1)再通过Base64编码得到的字符串;

Manifest-Version: 1.0
Created-By: 1.8.0_92 (Oracle Corporation)

Name: res/drawable-hdpi-v4/abc_list_longpressed_holo.9.png
SHA1-Digest: KQunCQh0E4bP0utgN0cHdQr9OwA=

Name: res/drawable-xxhdpi-v4/abc_ic_star_half_black_16dp.png
SHA1-Digest: EikVyBT5I7pmbJO2k8qF0V5hUc0=

2.CERT.SF的内容:
1.MANIFEST.MF文件的摘要的Base64编码
2.MANIFEST.MF文件中每个条目的摘要的Base64编码(即二次SHA1+Base64得到的字符串)

Signature-Version: 1.0
SHA1-Digest-Manifest: odZIAbrTVCfKGy6HEd5+gdBHw0I=
Created-By: 1.8.0_92 (Oracle Corporation)

Name: res/drawable-hdpi-v4/abc_list_longpressed_holo.9.png
SHA1-Digest: xcQ0bHWRc+R9tuxQ3wgY1a2eY0k=

Name: res/drawable-xxhdpi-v4/abc_ic_star_half_black_16dp.png
SHA1-Digest: pj+V2r2pJOgJwGGNpeqxnykl0Nc=

3.CERT.RSA的内容:
cert.rsa中的是二进制内容,保存了签名者的证书和CERT.SF文件的签名;

签名过程:
APK签名_第2张图片校验过程:
1.计算CERT.SF文件的摘要得到A,并且用公钥将CERT.RSA文件中的签名解密得到B,将二者对比验证CERT.SF正确性
2.计算MANIFEST.MF文件的摘要,与CERT.SF记录中的MANIFEST.MF摘要对比,验证MANIFEST.MF文件未被篡改
3.逐一计算MANIFEST文件中的每个条目的摘要,并与CERT.SF记录中的对比,验证MANIFEST中的每条记文件未被篡改
4.逐一计算APK中的每个文件的摘要,并与MANIFEST记录中的对比,验证APK中的每个文件未被篡改;

JAR签名缺点:
1.要对每个文件进行摘要计算,导致安装会很慢;
2.META-INF目录自己本身是不进行签名校验过程的
所以Android 7.0推出了新的签名方案V2:

V2(Full APK Signature):

V2签名是Android7.0引入的;
其中V1是必选的,否则在7.0版本以下的系统会显示未安装;
如果在Android7.0以上版本上运行建议选则V1和V2,选择了V2版本后在7.0以上的系统会走V2校验

V2签名的官方解释是:
1.签名块现在位于ZIP中央目录之前;
2.签名是在整个APK文件的二进制内容上计算和验证的,而不是在v1的归档文件中解压缩文件内容
3…一个APK可以同时由v1和v2签名同时签署,所以它仍然可以向后兼容以前的Android版本

ZIP文件结构:
zip文件分为3部分:

数据区
此区块包含了zip中所有文件的记录,是一个列表,每条记录包含:文件名、压缩前后size、压缩后的数据等;

中央目录
存放目录信息,也是一个列表,每条记录包含:文件名、压缩前后size、本地文件头的起始偏移量等。通过本地文件头的起始偏移量即可找到压缩后的数据;

中央目录结尾记录
标识中央目录结尾,包含:中央目录条目数、size、起始偏移量、zip文件注释内容等。
V2方案为加强数据完整性保证,不在数据区和中央目录中插入数据,在数据区和中央目录 之间插入一个APK签名分块,
APK签名_第3张图片摘要和签名大致计算过程:
1.将1,3,4块的内容拆分成1MB的数据块;
2.计算每个数据块的摘要;
3.把第二步中计算的到的摘要连接在一起再计算一次摘要;
4.使用3生成的摘要生成签名

校验过程:
1.找到APK 签名分块 v2 分块。如果 v2 分块存在,则继续执行第 2 步。否则,回退至使用 v1 方案验证 APK。
2.根据V2分块的签名计算出摘要
3.根据1,3,4分块计算出一个摘要值
4.对比两个摘要值,通过验证

总结:

两种签名的区别
Jar签名是针对ZIP所有文件依次进行签名
V2签名把整个APK当成一个整体进行签名

JAR签名的劣势:
需对所有文件进行hash校验,速度较慢;
只保证了APK内各文件的完整性,APK(zip包)其它内容的完整性未保证。

V2签名的优势
只需进行一次hash校验,速度快;
不需要计算所有文件的摘要,以分块形式进行hash,支持并行计算。
除保证了APK内各文件的完整性,APK(zip包)中数据区、中央目录和中央目录结尾记录的完整性均得到了保证。

参考:
https://blog.csdn.net/zwjemperor/article/details/81051120

你可能感兴趣的:(APK签名)