尝试修复从APK文件中读取公钥耗时过长的问题

This commit is contained in:
juntao
2020-05-09 20:52:35 +08:00
parent 7a71e457ef
commit be20d1fec6

View File

@ -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);
}