获取已安装或未安装的apk签名

不说废话,只上代码:

package com.example.getapksign;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends ActionBarActivity {

	private static final String TAG = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	public void getAPKSign(View view) {
		Signature[]  signatures=showUninstallAPKSignatures("/mnt/sdcard/360.apk");
		parseSignature(signatures[0].toByteArray());
		getSingInfo("com.lbe.security.miui");
		
	}

	public Signature[]  showUninstallAPKSignatures(String apkPath) {
		String PATH_PackageParser = "android.content.pm.PackageParser";
		try {
			// apk包的文件路径
			// 这是一个Package 解释器, 是隐藏的
			// 构造函数的参数只有一个, apk文件的路径
			// PackageParser packageParser = new PackageParser(apkPath);
			Class pkgParserCls = Class.forName(PATH_PackageParser);
			Class[] typeArgs = new Class[1];
			typeArgs[0] = String.class;
			Constructor pkgParserCt = pkgParserCls.getConstructor(typeArgs);
			Object[] valueArgs = new Object[1];
			valueArgs[0] = apkPath;
			Object pkgParser = pkgParserCt.newInstance(valueArgs);
			Log.i(TAG, "pkgParser:" + pkgParser.toString());
			// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
			DisplayMetrics metrics = new DisplayMetrics();
			metrics.setToDefaults();
			// PackageParser.Package mPkgInfo = packageParser.parsePackage(new
			// File(apkPath), apkPath,
			// metrics, 0);
			typeArgs = new Class[4];
			typeArgs[0] = File.class;
			typeArgs[1] = String.class;
			typeArgs[2] = DisplayMetrics.class;
			typeArgs[3] = Integer.TYPE;
			Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
					"parsePackage", typeArgs);
			valueArgs = new Object[4];
			valueArgs[0] = new File(apkPath);
			valueArgs[1] = apkPath;
			valueArgs[2] = metrics;
			valueArgs[3] = PackageManager.GET_SIGNATURES;
			Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
					valueArgs);

			typeArgs = new Class[2];
			typeArgs[0] = pkgParserPkg.getClass();
			typeArgs[1] = Integer.TYPE;
			Method pkgParser_collectCertificatesMtd = pkgParserCls
					.getDeclaredMethod("collectCertificates", typeArgs);
			valueArgs = new Object[2];
			valueArgs[0] = pkgParserPkg;
			valueArgs[1] = PackageManager.GET_SIGNATURES;
			pkgParser_collectCertificatesMtd.invoke(pkgParser, valueArgs);
			// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
			Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField(
					"mSignatures");
			Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);

			Log.i(TAG, info[0].toCharsString());
			return info;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private String getSign(Context context) {
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> apps = pm
				.getInstalledPackages(PackageManager.GET_SIGNATURES);
		Iterator<PackageInfo> iter = apps.iterator();
		while (iter.hasNext()) {
			PackageInfo packageinfo = iter.next();
			String packageName = packageinfo.packageName;
			if (packageName.equals(context.getPackageName())) {
				Log.i(TAG, packageinfo.signatures[0].toCharsString());
				return packageinfo.signatures[0].toCharsString();
			}
		}
		return null;
	}
	
	public void getSingInfo(String pkgName) {
		try {
			PackageInfo packageInfo = getPackageManager().getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
			Signature[] signs = packageInfo.signatures;
			Signature sign = signs[0];
			parseSignature(sign.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void parseSignature(byte[] signature) {
		try {
			CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
			X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
			String pubKey = cert.getPublicKey().toString();
			String signNumber = cert.getSerialNumber().toString();
			System.out.println("signName:" + cert.getSigAlgName());
			System.out.println("pubKey:" + pubKey);
			System.out.println("signNumber:" + signNumber);
			System.out.println("subjectDN:"+cert.getSubjectDN().toString());
		} catch (CertificateException e) {
			e.printStackTrace();
		}
	}
}

http://blog.csdn.net/wulianghuan/article/details/18400581


应各位网友的要求和反应,反射调用android.content.pm.PackageParser类函数在android5.0以上系统会出现崩溃,原因是:android5.0以上android.content.pm.PackageParser的构造函数已经改变了,新的解决方法如下,我自己测试android 5.0 android6.0手机通过:

另外大家如果存在什么问题请留言,关注度高的问题我会找时间回复和解决。

package com.yunshouhu.loaddex;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;

@SuppressLint("NewApi")
public class MainActivity extends Activity {

	private static final String TAG = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}


	public void getAPKSign(View view) {
		Signature[]  signatures;
		if(Build.VERSION.SDK_INT>=21)
		{
			signatures=showUninstallAPKSignaturesAfter21("/mnt/sdcard/qqemail.apk");			
		}else{
			signatures=showUninstallAPKSignatures("/mnt/sdcard/qqemail.apk");
		}
		parseSignature(signatures[0].toByteArray());
		getSingInfo("com.android.phone");
		
	}

	//反射调用android.content.pm.PackageParser的时候注意:android 4.4以下是有参构造 android5.0以上是无参构造函数了。
	//下面是android5.0以上的解决方法
		public Signature[]  showUninstallAPKSignaturesAfter21(String apkPath) {
			String PATH_PackageParser = "android.content.pm.PackageParser";
			try {
				// PackageParser packageParser = new PackageParser();
				
				Class pkgParserCls = Class.forName(PATH_PackageParser);
				Constructor pkgParserCt = pkgParserCls.getConstructor( new Class[]{});			
				Object pkgParser = pkgParserCt.newInstance(new Object[]{});
				Log.i(TAG, "pkgParser:" + pkgParser.toString());
				// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
				DisplayMetrics metrics = new DisplayMetrics();
				metrics.setToDefaults();
				//方法原型: public Package parsePackage(File packageFile, int flags) throws PackageParserException 
				
				Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
						"parsePackage",  new Class[]{File.class,int.class});
				
				Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
						new Object[]{new File(apkPath),PackageManager.GET_SIGNATURES});

				Method pkgParser_collectCertificatesMtd = pkgParserCls
						.getDeclaredMethod("collectCertificates", new Class[]{ pkgParserPkg.getClass(),Integer.TYPE});
						
				pkgParser_collectCertificatesMtd.invoke(pkgParser, new Object[]{pkgParserPkg,PackageManager.GET_SIGNATURES});
				// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
				Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
				Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);

				Log.i(TAG, info[0].toCharsString());
				return info;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	//反射调用android.content.pm.PackageParser的时候注意:android 4.4以下是有参构造 android5.0以上是无参构造函数了。
	//下面是android5.0以下的解决方法
	public Signature[]  showUninstallAPKSignatures(String apkPath) {
		String PATH_PackageParser = "android.content.pm.PackageParser";
		try {
			// apk包的文件路径
			// 这是一个Package 解释器, 是隐藏的
			// 构造函数的参数只有一个, apk文件的路径
			// PackageParser packageParser = new PackageParser(apkPath);
			Class pkgParserCls = Class.forName(PATH_PackageParser);
			Constructor pkgParserCt = pkgParserCls.getConstructor( new Class[]{String.class});
			
			Object pkgParser = pkgParserCt.newInstance(new Object[]{apkPath});
			Log.i(TAG, "pkgParser:" + pkgParser.toString());
			// 这个是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
			DisplayMetrics metrics = new DisplayMetrics();
			metrics.setToDefaults();
			
			//PackageParser.Package mPkgInfo = public Package parsePackage(File sourceFile, String destCodePath,DisplayMetrics metrics, int flags) 

			Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
					"parsePackage",  new Class[]{File.class, String.class,DisplayMetrics.class,Integer.TYPE});
			
			Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
					new Object[]{new File(apkPath), apkPath,metrics,PackageManager.GET_SIGNATURES});

			Method pkgParser_collectCertificatesMtd = pkgParserCls
					.getDeclaredMethod("collectCertificates", new Class[]{ pkgParserPkg.getClass(),Integer.TYPE});
					
			pkgParser_collectCertificatesMtd.invoke(pkgParser, new Object[]{pkgParserPkg,PackageManager.GET_SIGNATURES});
			// 应用程序信息包, 这个公开的, 不过有些函数, 变量没公开
			Field packageInfoFld = pkgParserPkg.getClass().getDeclaredField("mSignatures");
			Signature[] info = (Signature[]) packageInfoFld.get(pkgParserPkg);

			Log.i(TAG, info[0].toCharsString());
			return info;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private String getSign(Context context) {
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> apps = pm
				.getInstalledPackages(PackageManager.GET_SIGNATURES);
		Iterator<PackageInfo> iter = apps.iterator();
		while (iter.hasNext()) {
			PackageInfo packageinfo = iter.next();
			String packageName = packageinfo.packageName;
			if (packageName.equals(context.getPackageName())) {
				Log.i(TAG, packageinfo.signatures[0].toCharsString());
				return packageinfo.signatures[0].toCharsString();
			}
		}
		return null;
	}
	
	public void getSingInfo(String pkgName) {
		try {
			PackageInfo packageInfo = getPackageManager().getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
			Signature[] signs = packageInfo.signatures;
			Signature sign = signs[0];
			parseSignature(sign.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void parseSignature(byte[] signature) {
		try {
			CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
			X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(signature));
			String pubKey = cert.getPublicKey().toString();
			String signNumber = cert.getSerialNumber().toString();
			System.out.println("signName:" + cert.getSigAlgName());
			System.out.println("pubKey:" + pubKey);
			System.out.println("signNumber:" + signNumber);
			System.out.println("subjectDN:"+cert.getSubjectDN().toString());
		} catch (CertificateException e) {
			e.printStackTrace();
		}
	}
}






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值