• 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

  • 相关阅读:
    【ARM-Linux开发】C语言getcwd()函数:取得当前的工作目录
    【ARM-Linux开发】C语言getcwd()函数:取得当前的工作目录
    【ARM-Linux开发】Gstreamer+QT+摄像头 编程总结
    【ARM-Linux开发】Gstreamer+QT+摄像头 编程总结
    【ARM-Linux开发】 pkg-config的用法
    【ARM-Linux开发】 pkg-config的用法
    【ARM-Linux开发】gstreamer教程及在DM3730上的应用
    【ARM-Linux开发】gstreamer教程及在DM3730上的应用
    【ARM-Linux开发】打包解包命令
    【ARM-Linux开发】打包解包命令
  • 原文地址:https://www.cnblogs.com/Jclemo/p/6993880.html
Copyright © 2020-2023  润新知