如何根据 APK 文件获取应用签名时间

Posted

技术标签:

【中文标题】如何根据 APK 文件获取应用签名时间【英文标题】:How to get app signing time based on APK file 【发布时间】:2017-11-04 00:48:01 【问题描述】:

我正在进行一个分析 APK 文件以检测恶意软件应用程序的项目,我想知道如何提取签名时间而不是打包时间。这是我从一篇论文中读到的一个功能,它似乎非常有用。

【问题讨论】:

Determine signing certificate from an APK。一旦你有了证书,我相信你可以做一些事情,比如提取时间。 【参考方案1】:

据我所知,至少有 3 种方法可以获取诸如签约时间之类的信息。首先是使用keytool

$ keytool -printcert -jarfile sample.apk
Signer #1:

Signature:

Owner: CN=GService inc, OU=G Service inc, O=G, L=New York, ST=New York, C=US
Issuer: CN=GService inc, OU=G Service inc, O=G, L=New York, ST=New York, C=US
Serial number: 6f30f864
Valid from: Thu Dec 17 04:12:27 PST 2015 until: Wed Dec 12 04:12:27 PST 2035
Certificate fingerprints:
     MD5:  4D:36:65:14:59:5B:74:8F:2C:9D:92:30:F6:1D:90:8A
     SHA1: A8:85:7B:72:4C:EE:55:83:09:D5:AC:5D:1A:02:80:C5:F6:83:2B:40
     SHA256: 04:A7:24:9F:35:D5:8D:7E:F6:0F:73:81:35:5D:23:16:0D:FC:EA:61:C4:15:61:CC:06:8D:36:D9:C6:55:12:B7
     Signature algorithm name: SHA256withRSA
     Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: C1 C5 19 32 72 47 46 C5   01 CC 4B AF 12 40 3D D2  ...2rGF...K..@=.
0010: B5 52 45 5E                                        .RE^
]
]

这将为您提供创建证书的可能时间:Thu Dec 17 04:12:27 PST 2015

第二种是使用jarsigner

$ jarsigner -verify -verbose sample.apk

sm      4284 Wed Apr 13 11:03:18 PDT 2016 androidManifest.xml
sm      9193 Wed Apr 13 11:03:18 PDT 2016 res/drawable-hdpi-v4/ic_launcher.png
sm      5057 Wed Apr 13 11:03:18 PDT 2016 res/drawable-mdpi-v4/ic_launcher.png
sm     14068 Wed Apr 13 11:03:18 PDT 2016 res/drawable-xhdpi-v4/ic_launcher.png
sm      1408 Wed Apr 13 11:03:18 PDT 2016 resources.arsc
sm     20388 Wed Apr 13 11:03:18 PDT 2016 classes.dex
s        523 Wed Apr 13 11:03:18 PDT 2016 META-INF/MANIFEST.MF
         576 Wed Apr 13 11:03:18 PDT 2016 META-INF/CERT.SF
        1368 Wed Apr 13 11:03:18 PDT 2016 META-INF/CERT.RSA

  s = signature was verified
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  i = at least one certificate was found in identity scope

这将为您提供 APK 中所有条目的最后修改时间。在此 APK 中,它们都是相同的,但有时会有所不同。所有最后修改时间可能必须大于“有效起始”日期。

第三个选项是在 Java 中以编程方式使用 JarFile

private static void printCertInfo(String jarPath) throws Exception 
    // verify = true is key here
    JarFile apkFile = new JarFile(jarPath, true);
    JarEntry androidManifestEntry = apkFile.getJarEntry("AndroidManifest.xml");
    if (androidManifestEntry == null) 
        System.err.println("APK has no AndroidManifest.xml");
        System.exit(-1);
    

    // Need to fully read stream to verify cert
    System.out.println("Android manifest probably signed: " + androidManifestEntry.getLastModifiedTime());

    ByteStreams.copy(apkFile.getInputStream(androidManifestEntry), ByteStreams.nullOutputStream());
    // Assuming only signed with a single cert (not always true, but you get the idea)
    X509Certificate cert = (X509Certificate) androidManifestEntry.getCertificates()[0];
    System.out.println("Android manifest cert probably created: " + cert.getNotBefore());
    System.out.println("Full cert: " + cert.toString());

您可能认为您可以使用androidManifestEntry.getCodeSigners()[0].getTimestamp(),但它始终是null,我不确定它是什么。上面的代码给出了这个输出:

Android manifest probably signed: 2016-04-13T18:03:18Z
Android manifest cert probably created: Thu Dec 17 04:12:27 PST 2015
Full cert: [
[
  Version: V3
  Subject: CN=GService inc, OU=G Service inc, O=G, L=New York, ST=New York, C=US
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  // ** SNIP -- you get the idea **

【讨论】:

以上是关于如何根据 APK 文件获取应用签名时间的主要内容,如果未能解决你的问题,请参考以下文章

如何查看android 应用签名

您必须使用与您要验证的应用程序相同的签名签署一个 apk - blockchainds.com:如何通过 Android Studio 签署 apk 文件?

AppCan移动开发技巧:3步走,获取移动APP签名信息

如何判断 Android 应用的 Apk 签名是不是一致

android 微信开放平台,如何获取应用签名

PHP获取安卓apk包里的apk签名