工做須要須要對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; }