现在的位置: 首页 > 综合 > 正文

如何获取未安装的APK的签名

2014年10月11日 ⁄ 综合 ⁄ 共 2179字 ⁄ 字号 评论关闭
private Signature[] getSignatures(String archiveFilePath) {
        //必须使用反射机制才能获取未安装apk的签名信息
        final String PACKAGEPARSER_CLASS_NAME = "android.content.pm.PackageParser";
        final String PARSEPACKAGE_METHOD_NAME = "parsePackage";
        final String SUBCLASS_PACKAGE_CLASS_NAME = "Package";
        final String COLLECTCERTIFICATES_METHOD_NAME = "collectCertificates";
        final String GENERATEPACKAGEINFO_METHOD_NAME = "generatePackageInfo";
        try {
            //根据反射获取隐藏类
            Class<?> parserClass = Class.forName(PACKAGEPARSER_CLASS_NAME);

            //获取类的构造方法
            Constructor<?> cons = parserClass.getConstructor(String.class);

            //调用构造方法,构造类实例
            Object packageParser = cons.newInstance(archiveFilePath);

            
            //获取名为"parsePackage"的方法
            Method parseMethod = parserClass.getMethod(PARSEPACKAGE_METHOD_NAME, File.class, String.class, DisplayMetrics.class, int.class);

            //遍历类的子类集,找到Package内部类
            Class<?>[] subClasses = parserClass.getClasses();
            Class<?> packageClass = null;
            for(int i=0; i<subClasses.length; i++) {
                if(subClasses[i].getName().equals(PACKAGEPARSER_CLASS_NAME+"$"+SUBCLASS_PACKAGE_CLASS_NAME)) {
                    packageClass = subClasses[i];
                }
            }
            
            DisplayMetrics metrics = new DisplayMetrics();
            metrics.setToDefaults();
            
            //调用parseMethod方法,获取Package的实例
            Object pkg = parseMethod.invoke(packageParser, new File(archiveFilePath), archiveFilePath, metrics, 0);
            if(pkg == null) {
                Log.e("解析apk包失败");
                return null;
            }
            
            //获取名为"collectCertificates"的方法
            Method certMethod = parserClass.getMethod(COLLECTCERTIFICATES_METHOD_NAME, packageClass, int.class);

            //调用collectCertificates方法,收集证书
            certMethod.invoke(packageParser, pkg, 0);
            
            //获取名为"generatePackageInfo"的方法
            Method genMethod = parserClass.getMethod(GENERATEPACKAGEINFO_METHOD_NAME, packageClass, int[].class, int.class, long.class, long.class);

            //最后调用generatePackageInfo方法,得到签名信息
            PackageInfo pi = (PackageInfo)genMethod.invoke(packageParser, pkg, null, PackageManager.GET_SIGNATURES, 0, 0);
            return pi.signatures;
            
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
        }
        return null;
    }

抱歉!评论已关闭.