V2多渠道打包分析丶工具开发

V2签名分析简单过一下V1签名多渠道方案V1签名原理V1多渠道方案(1)V1多渠道方案(2)V1多渠道方案(3)V2渠道原理V2多渠道包实现原理定位签名块位置签名块中增加渠道信息修改EOCD中央偏移量结尾简单过一下V1签名多渠道方案V1签名原理v1 签名方案重要的原理就是对 apk 中所有的文件计算摘要 保存到 MANIFEST.MF 文件中;然后计算 MANIFEST.MF 中每个条目的摘...
摘要由CSDN通过智能技术生成

简单过一下V1签名多渠道方案

V1签名原理

v1 签名方案重要的原理就是对 apk 中所有的文件计算摘要 保存到 MANIFEST.MF 文件中;然后计算 MANIFEST.MF 中每个条目的摘要以及 MANIFEST.MF 本身的摘要,保存到 CERT.SF 文件中;最后用私钥对 CERT.SF 文件加密,然后保存到 CERT.RSA 文件中(这个文件还包含了签名算法、公钥信息)

(1) .MF文件

apk当中的原始文件信息用摘要算法如SHA1计算得到的摘要信息并用base64编码保存,以及对应采用的摘要算法如SHA1(这个算法的特性是不管多大的文件内容都能够得到长度相同的摘要信息但是不同的文件内容信息得到的摘要信息肯定不同)

(2) .SF文件

.MF文件的摘要信息以及.MF文件当中每个条目在用摘要算法计算得到的摘要信息并用base64编码保存

(3) .RSA文件

存放证书信息,公钥信息,以及用私钥对.SF文件的加密数据即签名信息,这段数据是无法伪造的,除非有私钥,另外.RSA文件还记录了所用的签名算法等信息。

Apk包在安装的时候,是按照从(3)到(1)的顺序依次校验的,先用公钥还原签名信息,然后和.SF文件中的信息比对,然后用同样的摘要算法对.MF文件里面的每一个条目计算对应的摘要信息,然后比对.MF文件是否一致

V1多渠道方案(1)

向META-INF目录中创建文件写入渠道信息,因为在v1签名验证时候,并不会验证META-INF的除了.MF文件的其它文件

V1多渠道方案(2)

在APK的任意位置填写空文件夹(注意是空文件夹),在apk签名过程中,只会对apk中的所有文件进行摘要+签名的,不会对文件夹进行这样的操作(文件夹无法计算摘要),所以也不会验证这个文件夹

V1多渠道方案(3)

这个就要了解下APK结构(其实就是ZIP的结构)了,看下面的图
在这里插入图片描述
从图中我们能看出,有一个End of Central Directory的数据块,这块是什么呢?其实这块就是结尾信息,里面记录了部分信息,简称EOCD
在这里插入图片描述
我们主要看最后有一个注释长度的标识,那我们是不是可以通过这个加入渠道呢?当然可以,这个只是zip文件的一个注释字段,所以并不影响ZIP里面的文件,所以更不会影响APK的签名,Apk安装的前提是要把Zip解压,在进行验签名等过程,所以想要多渠道修改APK第一点就是保证Zip结构的正确,第二点才是不违背签名
只需要在Zip结尾处增加一个注释即可
逻辑代码:

  
    /**
     * 读取渠道信息
     * @throws IOException
     */
    private static void readCannel() throws IOException {
   
        File in = new File("/Users/wenyingzhi/Desktop/Study/apksign/app-out.apk");
        RandomAccessFile inR = new RandomAccessFile(in, "r");
        // 读取渠道长度(读取后4个字节)
        inR.seek(inR.length() - 4);
        ByteBuffer commentLengthBytes = ByteBuffer.allocate(4);
        commentLengthBytes.order(ByteOrder.LITTLE_ENDIAN);
        inR.readFully(commentLengthBytes.array(), commentLengthBytes.arrayOffset(), commentLengthBytes.capacity());
        // 得到注释长度了
        int commentLength = commentLengthBytes.getInt();
        System.out.println("当前注释长度:" + commentLength);
        // 移动文件指针,读取备注 文件长度 - 存储注释长度的int(占4位) -注释长度
        inR.seek(inR.length() - 4 - commentLength);
        // 读取注释内容
        ByteBuffer commentBytes = ByteBuffer.allocate(commentLength);
        commentBytes.order(ByteOrder.LITTLE_ENDIAN);
        inR.readFully(commentBytes.array(), commentBytes.arrayOffset(), commentBytes.capacity());
        S
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值