尝试修复从APK文件中读取公钥耗时过长的问题
This commit is contained in:
@ -14,9 +14,6 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import com.g00fy2.versioncompare.Version;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
@ -33,11 +30,18 @@ import org.json.JSONObject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
public class PackageUtils {
|
||||
|
||||
@ -178,7 +182,6 @@ public class PackageUtils {
|
||||
try {
|
||||
Signature sig = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
|
||||
// todo 目前测试的情况华为/小米/锤子均出现ANR
|
||||
// Fuck HUAWEI, 华为系统调用 getPackageArchiveInfo 获取魔羯 apk 的签名时会耗时超过5秒造成 ANR,没有找到解决方法
|
||||
// 如果可以的话尽量避免调用 getPackageArchiveInfo 方法
|
||||
Signature releaseSig = context.getPackageManager().getPackageArchiveInfo(apkFilePath, PackageManager.GET_SIGNATURES).signatures[0];
|
||||
@ -189,6 +192,28 @@ public class PackageUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 从 APK 中获取公钥(只支持包含 V1 签名的 APK
|
||||
private static String getApkSignatureFromFile(String apkFilePath) {
|
||||
try {
|
||||
ZipFile apkFile = new ZipFile(apkFilePath);
|
||||
Enumeration<?> entries = apkFile.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = ((ZipEntry) entries.nextElement());
|
||||
String entryName = entry.getName();
|
||||
if (entryName.contains("CERT.RSA")) {
|
||||
InputStream is = apkFile.getInputStream(entry);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate cert = (X509Certificate) cf.generateCertificates(is).toArray()[0];
|
||||
return cert.getPublicKey().toString();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 解析签名
|
||||
*/
|
||||
@ -254,6 +279,13 @@ public class PackageUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 从 APK 文件里读取公钥,与已安装的公钥比较判断是否一样
|
||||
String signatureFromApk = getApkSignatureFromFile(path);
|
||||
if (!TextUtils.isEmpty(signatureFromApk)
|
||||
&& signatureFromApk.equals(getApkSignatureByPackageName(context, packageName))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 若已安装的应用的签名与即将要安装的签名一致也返回 true
|
||||
return compareSignatureBetweenInstalledAppWithApk(context, packageName, path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user