Android 验证APK签名对比
最近OTT制定产品,其中有一条需求是只能安装自己公司签名的APK,所以在网上找了相关资料,最后总结功能实现如下:
1、签名错误码
frameworks/base/core/java/android/content/pm/PackageManager.java
public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25;
//添加签名错误码
public static final int INSTALL_FAILED_INVALID_SIGNATURES = -26;
2、对比签名
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
// 安装标识,区别打开APK和安装APK
private boolean mIsInstallApkFlag = false;
private void installPackageLI(InstallArgs args,
boolean newInstall, PackageInstalledInfo res) {
...
Log.i(TAG, "Start installation for package: " + pkg.packageName);
//add start 设置安装标识
mIsInstallApkFlag = true;
//add end
if (replace) {
replacePackageLI(pkg, parseFlags, scanMode, args.user,
installerPackageName, res);
} else {
installNewPackageLI(pkg, parseFlags, scanMode, args.user,
installerPackageName, res);
}
Log.i(TAG, "Installation done for package: " + pkg.packageName);
...
}
private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
int parseFlags, int scanMode, long currentTime, UserHandle user) {
...
if (!verifySignaturesLP(pkgSetting, pkg)) {
...
}
//add start 添加校验判断
// is xhw signatures
Signature[] xhwSignatures = getXWHSignatures(mContext,"com.ronbell.ott.setting");
if (xhwSignatures != null) {
if (compareSignatures(xhwSignatures, pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
mLastScanError = PackageManager.INSTALL_FAILED_INVALID_SIGNATURES;
return null;
}
}
//add end
// Verify that this new package doesn't have any content providers
// that conflict with existing packages. Only do this if the
// package isn't already installed, since we don't want to break
// things that are installed.
if ((scanMode&SCAN_NEW_INSTALL) != 0) {
...
}
//add methods 添加获取安装签名
private Signature[] getXWHSignatures(Context context, String packName){
if(!isSignature) return null; // 判断只有在安装的时候才起作用。
isSignature = false;
PackageManager pm = context.getPackageManager();
List<PackageInfo> apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
Iterator<PackageInfo> it = apps.iterator();
while(it.hasNext()){
PackageInfo info = it.next();
if(info.packageName.equals(packName)){
return info.signatures;
}
}
return null;
}
private boolean IsSignaturesSame(Signature[] s1, Signature[] s2) {
if(s1 == null || s2 == null ) {
return false ;
}
HashSet < Signature > set1 = new HashSet < Signature > ();
for (Signature sig : s1) {
set1.add(sig);
}
HashSet < Signature > set2 = new HashSet < Signature > ();
for (Signature sig : s2) {
set2.add(sig);
}
// Make sure s2 contains all signatures in s1.
if (set1.equals(set2)) {
return true ;
}
return false ;
}
//add end
3、安装失败提示
packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
...
//add start
} else if (msg.arg1 == PackageManager.INSTALL_FAILED_INVALID_SIGNATURES){
// Generic error handling for all other error codes.
centerTextDrawable.setLevel(1);
centerExplanationLabel = getExplanationFromErrorCode(msg.arg1);
centerTextLabel = R.string.install_failed_invalid_signature;
mLaunchButton.setVisibility(View.INVISIBLE);
} else {
// Generic error handling for all other error codes.
centerTextDrawable.setLevel(1);
centerExplanationLabel = getExplanationFromErrorCode(msg.arg1);
centerTextLabel = R.string.install_failed;
mLaunchButton.setVisibility(View.INVISIBLE);
}
...