1、如何获取Android的应用程序签名信息?
2、如何判断该签名是属于debug签名还是release签名?
进入正题:
1、获取应用的签名信息:
相信这个大家见过好多,即使不会的,也可百度得到,但是大部分度娘得到的答案你试验过之后会发现好多坑,通过以下这种方式得到的签名是一个非常长串的字符,和我们平常在第三方平台填的应用签名是不一样的,第三方平台填的签名信息是32位的。
- android.content.pm.Signature[] sigs = context.getPackageManager()
-
.getPackageInfo(context.getPackageName(), 64).signatures;
- String sign = sigs[0].toCharsString();
复制代码
那么如何获取32位签名呢?
需要将得到的这一长串字符利用如下的方法进行16进制转换成32位签名:通过MD5.hexdigest(sigs[0].toByteArray())得到最终的32位签名。
- public class MD5 {
- private static final char[] hexDigits = { 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 97, 98, 99, 100, 101, 102 };
- public static String hexdigest(String paramString) {
- try {
- String str = hexdigest(paramString.getBytes());
- return str;
- } catch (Exception localException) {
- }
- return null;
- }
- public static String hexdigest(byte[] paramArrayOfByte) {
- try {
- MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
- localMessageDigest.update(paramArrayOfByte);
- byte[] arrayOfByte = localMessageDigest.digest();
- char[] arrayOfChar = new char[32];
- int i = 0;
- int j = 0;
- while (true) {
- if (i >= 16)
- return new String(arrayOfChar);
- int k = arrayOfByte[i];
- int m = j + 1;
- arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
- j = m + 1;
- arrayOfChar[m] = hexDigits[(k & 0xF)];
- i++;
- }
- } catch (Exception localException) {
- }
- return null;
- }
- }
-
复制代码
如果你想检测上面的签名是否正确,你可以去下载微信开发平台或者QQ互联平台提供的签名查看工具apk来比较。
2、那么如何判断上面得到的签名是debug签名还是release签名呢?
1)、检测你AndroidMainfest.xml的"android:debuggable"属性设置为"true":
如下所示:
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:debuggable="true"
- android:theme="@style/AppTheme" >
复制代码
下面给出示例代码进行检测:
- private boolean isDebuggable(Context ctx)
- {
- boolean debuggable = false;
- PackageManager pm = ctx.getPackageManager();
- try
- {
- ApplicationInfo appinfo = pm.getApplicationInfo(ctx.getPackageName(), 0);
- debuggable = (0 != (appinfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
- }
- catch(NameNotFoundException e)
- {
- /*debuggable variable will remain false*/
- }
-
- return debuggable;
- }
复制代码
缺点:但是,这个方法有局限,相信很多人在开发应用的时候,其apllication标签下并没有填过android:debuggable属性,甚至有的人还不知道有这个属性可以填?
因此,也提供了以下几种方式去进行区分:
2)、检测你的应用程序是否是用debug key签名:
下面给出示例代码来进行检测:
- private static final String DEBUG_KEY = "你的debug签名";
- private boolean isDebuggable(Context ctx) {
- String TAG = "isDebuggable";
- boolean debuggable = false;
- try {
- PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(
- ctx.getPackageName(), PackageManager.GET_SIGNATURES);
- Signature signatures[] = pinfo.signatures;
- for (int i = 0; i < signatures.length; i++)
- Log.d(TAG, signatures[i].toCharsString());
- if (DEBUG_KEY.equals(signatures[0].toCharsString())) {
- debuggable = true;
- }
- } catch (NameNotFoundException e) {
- // debuggable variable will remain false
- }
- return debuggable;
- }
复制代码
缺点:这种方式也不是很理想,只针对单一应用,无法对所有应用进行签名判断。
那么,是否有比较完美的方式来判断呢?
根据google 官网提供的开发文档Signing your application,debug key 包含了以下几个属性值:"CN=Android Debug,O=Android,C=US",因此,提供下面第三种方式来判断。
3)、检测应用程序是否是用“CN=Android Debug,O=Android,C=US”的debug信息来签名的:
- private final static X500Principal DEBUG_DN = new X500Principal(
- "CN=Android Debug,O=Android,C=US");
- private static boolean isDebuggable(Context ctx) {
- boolean debuggable = false;
- try {
- PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES);
- Signature signatures[] = pinfo.signatures;
- for (int i = 0; i < signatures.length; i++) {
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
- X509Certificate cert = (X509Certificate) cf
- .generateCertificate(stream);
- debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
- if (debuggable)
- break;
- }
- } catch (NameNotFoundException e) {
- } catch (CertificateException e) {
- }
- return debuggable;
- }
复制代码
综上,建议使用第三种方式来判断签名是否为debug或者release版本。