解決 安卓9 簽名校驗報錯


最近有客戶反饋簽名校驗失敗了,后來查看發現是安卓9的系統改了方法了,調用簽名校驗的方法時拋出了異常
java.lang.NoSuchMethodException: collectCertificates [class android.content.pm.PackageParser$Package, int]

查看源碼發現
android-28的 PackageParser
public static void collectCertificates(Package pkg, boolean skipVerify)
throws PackageParserException {
collectCertificatesInternal(pkg, skipVerify);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
Package childPkg = pkg.childPackages.get(i);
childPkg.mSigningDetails = pkg.mSigningDetails;
}
}
android-28以下的 PackageParser
public static void collectCertificates(Package pkg, int parseFlags)
throws PackageParserException {
collectCertificatesInternal(pkg, parseFlags);
final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
Package childPkg = pkg.childPackages.get(i);
childPkg.mCertificates = pkg.mCertificates;
childPkg.mSignatures = pkg.mSignatures;
childPkg.mSigningKeys = pkg.mSigningKeys;
}
}

所以針對安卓9 修改了 簽名校驗方法如下:

public static String getAPKSignatures(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;
// 這個是與顯示有關的, 里面涉及到一些像素顯示等等, 我們使用默認的情況
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
Constructor pkgParserCt = null;
Object pkgParser = null;
if(Build.VERSION.SDK_INT>20){
pkgParserCt = pkgParserCls.getConstructor();
pkgParser = pkgParserCt.newInstance();
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", File.class, int.class);
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, new File(apkPath), PackageManager.GET_SIGNATURES);

        if(Build.VERSION.SDK_INT>=28){
        Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates", pkgParserPkg.getClass(), Boolean.TYPE);
        pkgParser_collectCertificatesMtd.invoke(pkgParser, pkgParserPkg, Build.VERSION.SDK_INT>28);
                Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates", pkgParserPkg.getClass(), Boolean.TYPE);
pkgParser_collectCertificatesMtd.invoke(pkgParser, pkgParserPkg, false);

Field mSigningDetailsField = pkgParserPkg.getClass().getDeclaredField("mSigningDetails"); // SigningDetails
mSigningDetailsField.setAccessible(true);

Object mSigningDetails = mSigningDetailsField.get(pkgParserPkg);
Field infoField = mSigningDetails.getClass().getDeclaredField("signatures");
infoField.setAccessible(true);
Signature[] info = (Signature[]) infoField.get(mSigningDetails);
return info[0].toCharsString();

}else{
Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates", pkgParserPkg.getClass(), Integer.TYPE);
pkgParser_collectCertificatesMtd.invoke(pkgParser, pkgParserPkg, PackageManager.GET_SIGNATURES);

Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
return info[0].toCharsString();
}


}else {
pkgParserCt = pkgParserCls.getConstructor(typeArgs);
pkgParser = pkgParserCt.newInstance(apkPath);
Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", File.class, String.class,DisplayMetrics.class,Integer.TYPE);
Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, new File(apkPath), apkPath,metrics,PackageManager.GET_SIGNATURES);
Method pkgParser_collectCertificatesMtd = pkgParserCls.getDeclaredMethod("collectCertificates", pkgParserPkg.getClass(),Integer.TYPE);
pkgParser_collectCertificatesMtd.invoke(pkgParser, pkgParserPkg,PackageManager.GET_SIGNATURES);
// 應用程序信息包, 這個公開的, 不過有些函數, 變量沒公開
Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);
return info[0].toCharsString();
}
} catch (Exception e) {
LogUtil.e("getAPKSignatures",e.getMessage());
e.printStackTrace();
}
return null;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM