How to get APK signing signature?

AndroidCertificateApkSignature

Android Problem Overview


Is there a way to retrieve the signature of the key used to sign an APK? I signed my APK with my key from my keystore. How can I retrieve it programmatically?

Android Solutions


Solution 1 - Android

You can access the APK's signing signature like this using the PackageManager class http://developer.android.com/reference/android/content/pm/PackageManager.html

Signature[] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (Signature sig : sigs)
{
    Trace.i("MyApp", "Signature hashcode : " + sig.hashCode());
}

I've used this to compare with the hashcode for my debug key, as a way to identify whether the APK is a debug APK or a release APK.

Solution 2 - Android

The package manager will give you the signing certificate for any installed package. You can then print out the details of the signing key, e.g.

final PackageManager packageManager = context.getPackageManager();
final List<PackageInfo> packageList = packageManager.getInstalledPackages(PackageManager.GET_SIGNATURES);

for (PackageInfo p : packageList) {
	final String strName = p.applicationInfo.loadLabel(packageManager).toString();
	final String strVendor = p.packageName;

	sb.append("<br>" + strName + " / " + strVendor + "<br>");

	final Signature[] arrSignatures = p.signatures;
	for (final Signature sig : arrSignatures) {
		/*
		* Get the X.509 certificate.
		*/
		final byte[] rawCert = sig.toByteArray();
		InputStream certStream = new ByteArrayInputStream(rawCert);

		try {
			CertificateFactory certFactory = CertificateFactory.getInstance("X509");
			X509Certificate x509Cert = (X509Certificate) certFactory.generateCertificate(certStream);

			sb.append("Certificate subject: " + x509Cert.getSubjectDN() + "<br>");
			sb.append("Certificate issuer: " + x509Cert.getIssuerDN() + "<br>");
			sb.append("Certificate serial number: " + x509Cert.getSerialNumber() + "<br>");
			sb.append("<br>");
		}
		catch (CertificateException e) {
			// e.printStackTrace();
		}
	}
}

Solution 3 - Android

My situation is that I have a pre-installed apk which use a wrong key-store . So directly install will give a fail because of inconsistent signature.I need to check the signature first to make sure it can be install smoothly.

Here is my solution.

As this code says, you can get the signature from an installed apk.

details:

Signature sig = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0];

Secondly: get the releaseApk hashCode to compare. In my case, I downloaded this apk from my server, and put it in the sd_card.

Signature releaseSig = context.getPackageManager().getPackageArchiveInfo("/mnt/sdcard/myReleaseApk.apk", PackageManager.GET_SIGNATURES).signatures[0];

Finally,compare the hashCode.

return sig.hashCode() == releaseSig.hashCode;

I have tried the code above, it works just fine. If the hashCode is different, you should just uninstall the old apk or if it's a system app and the device is rooted, you can just use runtime to remove it,and then install the new signature apk.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWaypointView Question on Stackoverflow
Solution 1 - AndroidOllie CView Answer on Stackoverflow
Solution 2 - AndroidYojimboView Answer on Stackoverflow
Solution 3 - AndroidShengfeng LiView Answer on Stackoverflow