zoukankan      html  css  js  c++  java
  • 20145307陈俊达_安卓逆向分析_软件包签名研究

    20145307陈俊达_安卓逆向分析_软件包签名研究

    引言

    写这篇文章的原因有两点,一,之前打算写两篇cydia逆向分析,可惜手机不能Cydia不支持5.0以上系统,无奈放弃。二,在写之前的博客的时候重新打包后传到安卓手机上的时候,出现了签名有问题,不能进行安装的问题,这就促使我想写一篇关于软件签名的文章。

    start

    安卓系统禁用更新签名不一致的apk,所以我们打包新的apk是肯定不能安装的。那么我们怎么来研究呢?推荐一款签名软件,鼎鼎大名的auto-sign,我们下载后进行解压,右键用VS code打开sign.bat文件。

    同时readme文件也帮助我们又一个很好的理解,两个签名密钥信息加上一个jar文件是这个程序的核心。testkey.x509.pem这个公钥文件和testkey.pk8这个私钥文件对xxx.apk签名之后变为signed的apk

    testkey.pk8 is the private key that is compatible with the recovery image included in this zip file
    testkey.x509.pem is the corresponding certificate/public key

    使用方法:
    java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip update_signed.zip

    那么我们来看看签名前后有什么变化,签名后多了一个叫做META-INF的文件夹,里面有三个文件,分别为 MANIFEST.MF 、 CERT.SF 、 CERT.RSA

    我们用jd-gui工具打开signapk.jar,找到主函数 main 看看代码

      public static void main(String[] args) {
        if (args.length != 4) {
          System.err.println("Usage: signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar");
    
          System.exit(2);
        }
    
        JarFile inputJar = null;
        JarOutputStream outputJar = null;
        try
        {
          X509Certificate publicKey = readPublicKey(new File(args[0]));
          PrivateKey privateKey = readPrivateKey(new File(args[1]));
          inputJar = new JarFile(new File(args[2]), false);
          outputJar = new JarOutputStream(new FileOutputStream(args[3]));
          outputJar.setLevel(9);
    
          Manifest manifest = addDigestsToManifest(inputJar);
          manifest.getEntries().remove("META-INF/CERT.SF");
          manifest.getEntries().remove("META-INF/CERT.RSA");
          outputJar.putNextEntry(new JarEntry("META-INF/MANIFEST.MF"));
          manifest.write(outputJar);
    
          Signature signature = Signature.getInstance("SHA1withRSA");
          signature.initSign(privateKey);
          outputJar.putNextEntry(new JarEntry("META-INF/CERT.SF"));
          writeSignatureFile(manifest, new SignatureOutputStream(outputJar, signature));
    
          outputJar.putNextEntry(new JarEntry("META-INF/CERT.RSA"));
          writeSignatureBlock(signature, publicKey, outputJar);
    
          copyFiles(manifest, inputJar, outputJar);
        } catch (Exception e) {
          e.printStackTrace();
          System.exit(1);
        } finally {
          try {
            if (inputJar != null) inputJar.close();
            if (outputJar != null) outputJar.close(); 
          }
          catch (IOException e) { e.printStackTrace();
            System.exit(1);
          }
        }
      }
    

    addDigestsToManifest 这个函数,遍历 Apk 中所有文件,对非文件夹非签名文件的文件逐个生成 SHA1 数字签名信息,再 base64 编码。再写入我们之前提到过的manifest.mf文件中。

    大概格式

    Manifest-Version: 1.0
    
    Created-By: 1.0 (Android)
    
    Name: res/drawable-xhdpi/ic_launcher.png
    
    SHA1-Digest: xxxxxxxxxxxx
    
    Name: AndroidManifest.xml
    
    SHA1-Digest: xxxxxxxxxxxx
    

    如果你修改了apk的文件,那么它的sha1值肯定会对应改变,肯定是不会安装成功的。

    接下来对之前生成的 manifest 使用 SHA1withRSA 算法, 用私钥签名,writeSignatureFile 这个函数,最后生成 CERT.SF 文件

    总结

    这篇文主要是一些理论的东西,没有太多的实践操作,所以我没有贴太多的图片,主要是三个文件结合保证了apk文件下所有的每个文件都有对应的密钥进行加密保证了唯一性,不会被其他的文件篡改。所以也就解决了之前的疑问,为什么会出现了签名错误的问题。下篇文章打算做一些实际的东西,实际的软件,实际的游戏,去hack it

  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/Jclemo/p/6993880.html
Copyright © 2011-2022 走看看