Android获取32位应用签名及如何判断该签名为debug还是release

时间:2021-10-23 12:48:50
1、如何获取Android的应用程序签名信息?

2、如何判断该签名是属于debug签名还是release签名?

进入正题:

1、获取应用的签名信息:

相信这个大家见过好多,即使不会的,也可百度得到,但是大部分度娘得到的答案你试验过之后会发现好多坑,通过以下这种方式得到的签名是一个非常长串的字符,和我们平常在第三方平台填的应用签名是不一样的,第三方平台填的签名信息是32位的。
  1. android.content.pm.Signature[] sigs = context.getPackageManager()
  2. .getPackageInfo(context.getPackageName(), 64).signatures;
  3. String sign = sigs[0].toCharsString();
复制代码
那么如何获取32位签名呢?

需要将得到的这一长串字符利用如下的方法进行16进制转换成32位签名:通过MD5.hexdigest(sigs[0].toByteArray())得到最终的32位签名。
  1. public class MD5 {

  2.         private static final char[] hexDigits = { 48, 49, 50, 51, 52, 53, 54, 55,
  3.                         56, 57, 97, 98, 99, 100, 101, 102 };

  4.         public static String hexdigest(String paramString) {
  5.                 try {
  6.                         String str = hexdigest(paramString.getBytes());
  7.                         return str;
  8.                 } catch (Exception localException) {
  9.                 }
  10.                 return null;
  11.         }

  12.         public static String hexdigest(byte[] paramArrayOfByte) {
  13.                 try {
  14.                         MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
  15.                         localMessageDigest.update(paramArrayOfByte);
  16.                         byte[] arrayOfByte = localMessageDigest.digest();
  17.                         char[] arrayOfChar = new char[32];
  18.                         int i = 0;
  19.                         int j = 0;
  20.                         while (true) {
  21.                                 if (i >= 16)
  22.                                         return new String(arrayOfChar);
  23.                                 int k = arrayOfByte[i];
  24.                                 int m = j + 1;
  25.                                 arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
  26.                                 j = m + 1;
  27.                                 arrayOfChar[m] = hexDigits[(k & 0xF)];
  28.                                 i++;
  29.                         }
  30.                 } catch (Exception localException) {
  31.                 }
  32.                 return null;
  33.         }
  34. }
复制代码

如果你想检测上面的签名是否正确,你可以去下载微信开发平台或者QQ互联平台提供的签名查看工具apk来比较。

2、那么如何判断上面得到的签名是debug签名还是release签名呢?

1)、检测你AndroidMainfest.xml的"android:debuggable"属性设置为"true":

如下所示:

  1. <application
  2.         android:allowBackup="true"
  3.         android:icon="@drawable/ic_launcher"
  4.         android:label="@string/app_name"
  5.         android:debuggable="true"
  6.         android:theme="@style/AppTheme" >
复制代码

下面给出示例代码进行检测:
  1. private boolean isDebuggable(Context ctx)
  2. {
  3.     boolean debuggable = false;

  4.     PackageManager pm = ctx.getPackageManager();
  5.     try
  6.     {
  7.         ApplicationInfo appinfo = pm.getApplicationInfo(ctx.getPackageName(), 0);
  8.         debuggable = (0 != (appinfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
  9.     }
  10.     catch(NameNotFoundException e)
  11.     {
  12.         /*debuggable variable will remain false*/
  13.     }
  14.      
  15.     return debuggable;
  16. }
复制代码


缺点:但是,这个方法有局限,相信很多人在开发应用的时候,其apllication标签下并没有填过android:debuggable属性,甚至有的人还不知道有这个属性可以填?


因此,也提供了以下几种方式去进行区分:


2)、检测你的应用程序是否是用debug key签名:


下面给出示例代码来进行检测:
  1. private static final String DEBUG_KEY = "你的debug签名";

  2.         private boolean isDebuggable(Context ctx) {

  3.                 String TAG = "isDebuggable";

  4.                 boolean debuggable = false;
  5.                 try {
  6.                         PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(
  7.                                         ctx.getPackageName(), PackageManager.GET_SIGNATURES);
  8.                         Signature signatures[] = pinfo.signatures;

  9.                         for (int i = 0; i < signatures.length; i++)
  10.                                 Log.d(TAG, signatures[i].toCharsString());

  11.                         if (DEBUG_KEY.equals(signatures[0].toCharsString())) {
  12.                                 debuggable = true;
  13.                         }

  14.                 } catch (NameNotFoundException e) {
  15.                         // debuggable variable will remain false
  16.                 }

  17.                 return debuggable;
  18.         }
复制代码


缺点:这种方式也不是很理想,只针对单一应用,无法对所有应用进行签名判断。
那么,是否有比较完美的方式来判断呢?

根据google 官网提供的开发文档Signing your application,debug key 包含了以下几个属性值:"CN=Android Debug,O=Android,C=US",因此,提供下面第三种方式来判断。


3)、检测应用程序是否是用“CN=Android Debug,O=Android,C=US”debug信息来签名的:
  1. private final static X500Principal DEBUG_DN = new X500Principal(
  2.                         "CN=Android Debug,O=Android,C=US");

  3.         private static boolean isDebuggable(Context ctx) {
  4.                 boolean debuggable = false;
  5.                 try {
  6.                         PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES);
  7.                         Signature signatures[] = pinfo.signatures;
  8.                         for (int i = 0; i < signatures.length; i++) {
  9.                                 CertificateFactory cf = CertificateFactory.getInstance("X.509");
  10.                                 ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
  11.                                 X509Certificate cert = (X509Certificate) cf
  12.                                                 .generateCertificate(stream);
  13.                                 debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
  14.                                 if (debuggable)
  15.                                         break;
  16.                         }

  17.                 } catch (NameNotFoundException e) {
  18.                 } catch (CertificateException e) {
  19.                 }
  20.                 return debuggable;
  21.         }
复制代码

综上,建议使用第三种方式来判断签名是否为debug或者release版本。