zoukankan      html  css  js  c++  java
  • 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); 
      } 

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

  • 相关阅读:
    iOS NSData简单解析
    CocoaPods安装和使用教程
    iOS_ruby环境的配置
    ios进行打包
    Missing iOS Distribution signing identity问题解决
    iOS 打包
    效果类似于label从下往上滑(采用uiTableView实现)
    IOS开发效率之为Xcode添加常用的代码片段
    JS中!!的用法
    java 短路与(||)时报错The operator || is undefined for the argument type(s) int, boolean
  • 原文地址:https://www.cnblogs.com/caoxinyu/p/10568675.html
Copyright © 2011-2022 走看看