毕设小结(一)Android程序包验证

本人由于毕设需求,需要从安装的APK中找到自个的APK,于是想到了利用公钥进行验证的方式(签名验证如果多个程序需要多个签名,索性使用公钥省事)

首先我们需要明白APK签名原理,在APK目录结构中META-INF目录是用存放签名校验等数据的,其中包括以下文件:MANIFEST.MF,CERT.SF,CERT.RSA。

整个签名过程如下图:


毕设小结(一)Android程序包验证_第1张图片


其中MANIFEST.MF文件存放了APK包中所有文件生成的SHA1摘要的Base64编码,使用UE可以看到以下内容:




而CERT.SF文件是对MANIFEST.MF的SHA1摘要,以及之前文件生成的摘要的再次SHA1摘要,最后都在分别进行Base64编码。使用UE可以看到以下内容:


毕设小结(一)Android程序包验证_第2张图片


CERT.RSA文件就是关键的签名文件了,其同时也包含了证书相关的信息,我们可以使用MiniCA2.0完成证书的导出查看:


毕设小结(一)Android程序包验证_第3张图片

导出了这个证书,之后可以查看其中内容



证书中的各个信息就都能看到了,之后可以查看公钥,值得注意的是,在图上所示的前9个字节中30 82 01 0a 02 82 01 01 00,是用来表示是什么算法产生的公钥这里是RSA.

最后的5个字节(这里没有展示完全自个查看解决)02 03 01 00 01 也是相关的标识,详细可以查看X509证书结构。而中间的内容就是我们的公钥。我们可以通过公钥标识我们

的身份。我是在服务中实现的,代码如下:

@Override
	public void onStart(Intent intent, int startId) {
		Log.i(TAG, "checksignatureservice start");
		super.onStart(intent, startId);
		PackageManager pm = getPackageManager();
		List<PackageInfo> packInfo = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
		Iterator<PackageInfo> iter = packInfo.iterator();
		ApplicationInfo appInfo = null;
		while (iter.hasNext()) {
			PackageInfo pi = (PackageInfo) iter.next();
			appInfo = pi.applicationInfo;
			if((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0){		
				continue;
			}else{
				//不是系统程序
				Log.d(TAG,pi.packageName);
				String key = getPublicKey(pi.signatures[0].toByteArray());
				if (key.equals(myRsaKey)) {
					Log.i(TAG,"It is my app");
				}		        
			}  		
		}
	}

getPublicKey函数如下:

private String getPublicKey(byte[] signature) {
		try {
			CertificateFactory certFactory = CertificateFactory
					.getInstance("X.509");
			X509Certificate cert = (X509Certificate) certFactory
					.generateCertificate(new ByteArrayInputStream(signature));
			String publickey = cert.getPublicKey().toString();
			publickey = publickey.substring(publickey.indexOf("modulus: ") + 9,
					publickey.indexOf("\n", publickey.indexOf("modulus:")));		
			return publickey;			
		} catch (CertificateException e) {
			e.printStackTrace();
		}
		return null;
	}


这样就实现了公钥的比对,通过如此来验证APK是否自己发布的APK

你可能感兴趣的:(android,签名,程序验证)