工做须要须要对App进行签名校验,项目基于5.1开发。android
流程是提取一个现有app提取签名做为验证码,对未安装的应用获取签名进行对比校验。app
提取已安装应用签名函数
public static String getSingInfo(String pkgName, Context c) { try { PackageInfo packageInfo = c.getPackageManager().getPackageInfo(pkgName, PackageManager.GET_SIGNATURES); Signature[] signs = packageInfo.signatures; Signature sign = signs[0]; return sign.toCharsString(); // parseSignature(sign.toByteArray()); } catch (Exception e) { e.printStackTrace(); } return null; }
提取未安装应用签名,其中注释掉的是5.0之前的方法ui
public static 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); // Log.i(TAG, "pkgParser:" + pkgParser.toString()); // // 这个是与显示有关的, 里面涉及到一些像素显示等等, 咱们使用默认的状况 // 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; //以上方法在Android L之前能够用 Object pkgParser; Class pkgParserCls = Class.forName(PATH_PackageParser); Constructor<?> pkgParserCt; Class<?>[] typeArgs = {String.class}; Object[] valueArgs = {apkPath}; Method pkgParser_parsePackageMtd; Object pkgParserPkg; if (Build.VERSION.SDK_INT >= 21) { //noinspection NullArgumentToVariableArgMethod Class[] cNull = null; Object[] oNull = null; pkgParserCt = pkgParserCls.getConstructor(cNull); //noinspection NullArgumentToVariableArgMethod pkgParser = pkgParserCt.newInstance(oNull); typeArgs = new Class[2]; typeArgs[0] = File.class; typeArgs[1] = Integer.TYPE; pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs); valueArgs = new Object[2]; valueArgs[0] = new File(apkPath); valueArgs[1] = 0; pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); } else { pkgParserCt = pkgParserCls.getConstructor(typeArgs); pkgParser = pkgParserCt.newInstance(valueArgs); typeArgs = new Class<?>[]{File.class, String.class, DisplayMetrics.class, int.class}; pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs); DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); valueArgs = new Object[4]; valueArgs[0] = new File(apkPath); valueArgs[1] = apkPath; valueArgs[2] = metrics; valueArgs[3] = 0; pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); } // 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); Log.i(TAG, info[0].toCharsString()); return info[0].toCharsString(); } catch (Exception e) { e.printStackTrace(); } return null; }