I am trying to get the signatures from an apk file prior to installing, however I am getting null signingInfo object. The PackageInfo is properly populated with all of the other data related to the package.
If I install the apk, then use getPackageInfo, the signingInfo will be populated. Not sure why its failing to obtain it from the apk itself.
Am I missing something on getting a signature from an apk file?
// This call works after installing the apk, it is able to pull the signature without issues
@Override
public boolean isPackageSignatureValid(final String packageName)
{
try
{
android.content.pm.PackageManager pm = context.getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(packageName, android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES);
return validateSignature(packageInfo);
}
catch (android.content.pm.PackageManager.NameNotFoundException notFoundException)
{
return false;
}
}
// Calling this on the apk file prior to install, signingInfo is always null
@Override
public boolean isApkSignatureValid(final String apkFilePath)
{
android.content.pm.PackageManager pm = context.getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(apkFilePath, android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES);
return validateSignature(packageInfo);
}
private boolean validateSignature(final PackageInfo packageInfo)
{
Signature[] signatures;
if (packageInfo == null || packageInfo.signingInfo == null)
{
return false;
}
if (packageInfo.signingInfo.hasMultipleSigners())
{
signatures = packageInfo.signingInfo.getApkContentsSigners();
}
else
{
signatures = packageInfo.signingInfo.getSigningCertificateHistory();
}
ArrayList<Integer> packageHashes = new ArrayList<>();
for (Signature sig : signatures)
{
// I know this is not the best way of doing this, please ignore for now as its not the main issue
packageHashes.add(sig.hashCode());
}
return isHashValid(packageHashes);
}
GET_SIGNING_CERTIFICATES
flag is added starting from API level 28.
Before that you can use GET_SIGNATURES
.
If getPackageArchiveInfo()
still returns null in API 28+, you can back to the deprecated GET_SIGNATURES
flag.
Starting from API level Tiramisu, getPackageArchiveInfo()
is deprecated, and this version can be used instead which accepts PackageManager.PackageInfoFlags
flag set instead of PackageManager
flags.