APK安装时的过滤方式:包名白名单、证书认证

1.定义一些全局变量,文件位置:

Build.java (frameworks\base\core\java\android\os) 

        /**
         * 包管理方式名称<br>
         *     whitelist: 白名单方式
         *     certificate: 证书认证方式
         *     none: 不进行管理
         */
        public static String packageManage = "none";
        /**
         * 允许 Launch 显示的 APP 及 APP 白名单
         */
		public static String[] packageAllow = new String[]{	"com.baidu.searchbox", 
									"com.thinta.product.thintazlib",
									"com.thinta.product.x4usertool"};
        /**
         * 允许 Launch 显示的 APP的 证书存放路径
         */
		public static String certificatePath = "/system/etc/security/media.zip";

 

2.修改安装APK过程,在安装过程添加验证

修改文件的位置:

PackageManagerService.java (frameworks\base\services\core\java\com\android\server\pm) 

首先添加一个函数:

	private static HashSet<X509Certificate> getTrustedCerts(File keystore)
			throws IOException, GeneralSecurityException {
			HashSet<X509Certificate> trusted = new HashSet<X509Certificate>();
			if (keystore == null) {
				return trusted;
			}
			ZipFile zip = new ZipFile(keystore);
			try {
				CertificateFactory cf = CertificateFactory.getInstance("X.509");
				Enumeration<? extends ZipEntry> entries = zip.entries();
				while (entries.hasMoreElements()) {
					ZipEntry entry = entries.nextElement();
					InputStream is = zip.getInputStream(entry);
					try {
						trusted.add((X509Certificate) cf.generateCertificate(is));
					} finally {
						is.close();
					}
				}
			} finally {
				zip.close();
			}
			return trusted;
		}

修改的函数:private void installPackageLI(InstallArgs args, PackageInstalledInfo res) 

第一处修改:
     if(Build.ThintaCust.packageManage.equals("certificate")) tmp_flags = PackageManager.GET_SIGNATURES; final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | (onSd ? PackageParser.PARSE_ON_SDCARD : 0) | tmp_flags; 第二处修改: if(Build.ThintaCust.packageManage.equals("none")){ Log.d("XYP_DEBUG", "packageManage = none \n"); }else if(Build.ThintaCust.packageManage.equals("whitelist")){ Log.d("XYP_DEBUG", "packageManage = whitelist \n"); List<String> list = Arrays.asList(Build.ThintaCust.packageAllow); if(list.contains(pkg.packageName)){ Log.d("XYP_DEBUG", "can install \n"); }else{ Log.d("XYP_DEBUG", "forbid install \n"); res.setError(PackageManager.INSTALL_FAILED_USER_RESTRICTED, "installPackageLI, forbid install"); return; } }else if(Build.ThintaCust.packageManage.equals("certificate")){ int verify_pass = 0; try{ File file = new File(Build.ThintaCust.certificatePath); HashSet<X509Certificate> trusted = getTrustedCerts(file); CertificateFactory cf = CertificateFactory.getInstance("X.509"); for (X509Certificate c : trusted) { String tmp_public_key = c.getPublicKey().toString(); for(Signature sig : pkg.mSignatures) { X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(sig.toByteArray())); String tmp_key = cert.getPublicKey().toString(); if(tmp_public_key.equals(tmp_key)){ verify_pass = 1; break; } } if(verify_pass == 1) break; } if(verify_pass != 1){ Log.d("XYP_DEBUG", "forbid install \n"); res.setError(PackageManager.INSTALL_FAILED_USER_RESTRICTED, "installPackageLI, forbid install"); return; } }catch(FileNotFoundException e){ Log.d("XYP_DEBUG", e.toString()); }catch(CertificateException e){ Log.d("XYP_DEBUG", e.toString()); }catch(IOException e){ Log.d("XYP_DEBUG", e.toString()); }catch(GeneralSecurityException e){ Log.d("XYP_DEBUG", e.toString()); } }

3.证书的压缩方式:

zip -r media.zip media.x509.pem

直接用命令把*.x509.pem 打包成zip文件,然后放到目标板的合适位置;

用第一步中的certificatePath指向存放该zip文件的位置。 

posted on 2016-11-30 16:20  黑大米  阅读(2848)  评论(0编辑  收藏  举报

导航