有没有办法检查应用程序签名是否调试或发布?

问题描述:

我目前正在为开发人员开发使用RPC服务,但希望确保我可以区分另一个应用程序的调试密钥和他们的公钥。有没有办法检查另一个应用程序的密钥,并告诉它是否是调试密钥而不是已发布的应用程序密钥?有没有办法检查应用程序签名是否调试或发布?

这样做的目的是为了能够告诉当他们的应用程序正在开发或释放状态,我需要能够告诉他们是否应该访问我的dev的服务器或我的生产服务器。

+0

你们都提供了一些非常有用的信息。表决两个答案。 – 2011-10-11 15:52:44

默认情况下,Eclipse使用的androiddebugkey(例如)具有notAfter日期&时间,未来至多1年 - Android Market不接受这种短时间值 - 您可以使用它来区分开发者签署了构建?或者..你可以检查应用程序使用的publickey - 让他们用他们的应用程序的android.content.pm.Signature签署RPC请求?

 
PackageInfo pkgInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); 

for (Signature appSignature : pkgInfo.signatures) { 
    // javax.security - NOT java.security! 
    X509Certificate appCertificate = X509Certificate.getInstance(appSignature.toByteArray()); 
    // appCertificate.getNotAfter() can give you the date & time the cert expires 
    // appCertificate.getPublicKey() can give you the public key you sign the RPC requests with. 
    // appCertificate.getSubjectDN() will give you a Principal named "CN=Android Debug,O=Android,C=US" for any debug certificate that hasn't been handcrafted by the developer. 
} 
+0

谢谢你的帮助!它已经很久了,我几乎已经放弃了。这里的问题是关键是“默认”1年。我已经设置了25年的调试密钥......这就是为什么我需要能够分辨出差异。有什么想法吗? – 2011-10-11 15:40:50

+0

我认为这是正确的轨道。 getSubjectDN()绝对是一种可能性。你能告诉我你在哪里找到这些信息,所以我可以再研究一下吗? – 2011-10-11 15:46:34

+0

用这个指导做了一些进一步的研究后,我想出了一个有效的解决方案。它是多方面的,但尽可能多地考虑了情况。首先是检查日期。然后,SubjectDN。最后,在另一次失败时,我将公钥视为市场查询。当然,甚至没有接近完整的解决方案,但可以满足我的大部分需求。再次感谢这个令人敬畏的信息。 – 2011-10-11 21:50:18

static final String DEBUGKEY = 
     " key ";  


public static boolean signedWithDebugKey(Context context, Class<?> cls) 
{ 
    boolean result = false; 
    try { 
     PackageInfo pinfo = context.getPackageManager().getPackageInfo("your package name",PackageManager.GET_SIGNATURES); 
     Signature sigs[] = pinfo.signatures; 

     Log.d(TAG,sigs[0].toCharsString()); 

     if (DEBUGKEY.equals(sigs[0].toCharsString())) { 
      result = true; 
      Log.d(TAG,"package has been signed with the debug key"); 
     } else { 
      Log.d(TAG,"package signed with a key other than the debug key"); 
     } 

    } catch (android.content.pm.PackageManager.NameNotFoundException e) { 
     return false; 
    } 

    return result; 

} 

第一次使用debugkey运行此代码,这将总是返回false,但您会在Logcat中获得编码密钥。 复制该编码密钥,并替换DEBUGKEY的值“key”,它会正常工作。

+0

您需要解压缩签名,例如使用javax.security.X509Certificate - sigs [0] .toCharsString()不会返回“androiddebugkey”,它会返回一个大的十六进制编码的字符串。 – Jens 2011-10-03 09:12:08

+0

对不起,我修复了答案。 – xtr 2011-10-03 09:55:33

+1

static final String DEBUGKEY = " key ";这行似乎暗示我已经知道调试密钥,我是否正确?如果我是,我不可能知道调试密钥,因为它是由另一个开发人员提供的。我的API的工作方式是,对于调试应用程序,它可以免费用于测试,但对于已发布的应用程序,开发人员必须支付最低的费用才能进行集成。重要的是我知道密钥是调试还是发布而不知道密钥是什么。 – 2011-10-11 15:42:06