android获取未安装APK签名信息及MD5指纹

站在巨人的肩膀上写博客:
http://blog.csdn.net/wulianghuan/article/details/18400581

http://www.jb51.net/article/79894.htm

1.获取APK的签名信息

方法一:

    private String showUninstallAPKSignatures(String apkPath) {
        String PATH_PackageParser = "android.content.pm.PackageParser";
        try {
            // apk包的文件路径
            // 这是一个Package 解释器, 是隐藏的
            // 构造函数的参数只有一个, apk文件的路径
            // PackageParser packageParser = new PackageParser(apkPath);
            Class pkgParserCls = Class.forName(PATH_PackageParser);
            Class[] typeArgs = new Class[1];
            typeArgs[0] = String.class;
            Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
            Object[] valueArgs = new Object[1];
            valueArgs[0] = apkPath;
            Object pkgParser = pkgParserCt.newInstance(valueArgs);
            // 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
            DisplayMetrics metrics = new DisplayMetrics();
            metrics.setToDefaults();
            // PackageParser.Package mPkgInfo = packageParser.parsePackage(new
            // File(apkPath), apkPath,
            // metrics, 0);
            typeArgs = new Class[4];
            typeArgs[0] = File.class;
            typeArgs[1] = String.class;
            typeArgs[2] = DisplayMetrics.class;
            typeArgs[3] = Integer.TYPE;
            Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage",
                    typeArgs);
            valueArgs = new Object[4];
            valueArgs[0] = new File(apkPath);
            valueArgs[1] = apkPath;
            valueArgs[2] = metrics;
            valueArgs[3] = PackageManager.GET_SIGNATURES;
            Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

            typeArgs = new Class[2];
            typeArgs[0] = pkgParserPkg.getClass();
            typeArgs[1] = Integer.TYPE;
            Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates",
                    typeArgs);
            valueArgs = new Object[2];
            valueArgs[0] = pkgParserPkg;
            valueArgs[1] = PackageManager.GET_SIGNATURES;
            pkgParser_collectCertificatesMtd.invoke(pkgParser, valueArgs);
            // 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
            Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
            Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
            return info[0].toCharsString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

方法二:

 /** 
   * 从APK中读取签名 
   * @param file 
   * @return 
   * @throws IOException 
   */
  private static List<String> getSignaturesFromApk(File file) throws IOException { 
    List<String> signatures=new ArrayList<String>(); 
    JarFile jarFile=new JarFile(file); 
    try { 
      JarEntry je=jarFile.getJarEntry("AndroidManifest.xml"); 
      byte[] readBuffer=new byte[8192]; 
      Certificate[] certs=loadCertificates(jarFile, je, readBuffer); 
      if(certs != null) { 
        for(Certificate c: certs) { 
          String sig=toCharsString(c.getEncoded()); 
          signatures.add(sig); 
        } 
      } 
    } catch(Exception ex) { 
    } 
    return signatures; 
  } 

 /** 
   * 加载签名 
   * @param jarFile 
   * @param je 
   * @param readBuffer 
   * @return 
   */
  private static Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) { 
    try { 
      InputStream is=jarFile.getInputStream(je); 
      while(is.read(readBuffer, 0, readBuffer.length) != -1) { 
      } 
      is.close(); 
      return je != null ? je.getCertificates() : null; 
    } catch(IOException e) { 
    } 
    return null; 
  } 

/** 
   * 将签名转成转成可见字符串 
   * @param sigBytes 
   * @return 
   */
  private static String toCharsString(byte[] sigBytes) { 
    byte[] sig=sigBytes; 
    final int N=sig.length; 
    final int N2=N * 2; 
    char[] text=new char[N2]; 
    for(int j=0; j < N; j++) { 
      byte v=sig[j]; 
      int d=(v >> 4) & 0xf; 
      text[j * 2]=(char)(d >= 10 ? ('a' + d - 10) : ('0' + d)); 
      d=v & 0xf; 
      text[j * 2 + 1]=(char)(d >= 10 ? ('a' + d - 10) : ('0' + d)); 
    } 
    return new String(text); 
  } 

说明:方法一不管用的话,可以用方法二。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值