有没有一种方法来检查应用程序签名是调试还是已发布?

9
我正在开发RPC服务,供开发人员使用,但是我希望确保我能够区分另一个应用程序的调试密钥和其公共密钥。是否有一种方法可以检查另一个应用程序的密钥并确定它是否为调试密钥而不是已发布的应用程序密钥?
这样做的目的是为了能够知道他们的应用程序处于开发还是发布状态,因为我需要确定他们是否应该访问我的开发服务器还是生产服务器。

你们两位提供了非常有用的信息。给两个答案点赞。 - Fuzzical Logic
2个回答

5
默认情况下,Eclipse使用的androiddebugkey(例如)的notAfter 日期和时间最多只有1年 - Android Market不接受如此短的值 - 您可以使用该值来区分开发人员签名的版本?或者...您可以检查应用程序使用的公钥-请让他们使用其应用程序的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() 可以给出证书过期的日期和时间 // appCertificate.getPublicKey() 可以提供您用于签署RPC请求的公钥。 // appCertificate.getSubjectDN() 将为任何未被开发人员手工制作的调试证书提供名为“CN = Android Debug,O = Android,C = US”的主体。 }

谢谢你的帮助!我已经放弃很久了。问题在于密钥“默认”为1年。我已将我的调试密钥设置为25年...这就是为什么我需要能够区分它们的原因。有什么想法吗? - Fuzzical Logic
我认为这是正确的方向。getSubjectDN() 绝对是一个可能性。你能告诉我你在哪里找到这些信息吗?这样我可以进一步研究它。 - Fuzzical Logic
在遵循这个指南并进行了进一步的研究后,我想出了一个有效的解决方案。它是多部分的,但考虑到尽可能多的情况。首先是检查日期。然后是SubjectDN。最后,在另一个失败的情况下,我将公钥与市场查询匹配。当然,这还远远不是完整的解决方案,但已经满足了我大部分的需求。再次感谢这个令人惊叹的信息。 - Fuzzical Logic
是的,很不幸,人们经常会调整他们的密钥(至少在第一个密钥过期后的混乱时)- 或者更糟糕的是,将生产密钥塞入他们的调试密钥库中(..可怕的想法)。 - Jens

4
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”值,它就可以正常工作。


你需要解压签名,例如使用javax.security.X509Certificate - sigs[0].toCharsString(),它不会返回"androiddebugkey",而是返回一个大的十六进制编码字符串。 - Jens
1
<code>static final String DEBUGKEY = " key ";</code> 这行代码似乎在暗示我已经知道了调试密钥,我是正确的吗?如果是这样,那么我不可能知道调试密钥,因为它是由另一个开发者提供的。我的 API 工作方式是,对于调试应用程序,它可以免费使用进行测试,但对于发布的应用程序,开发者必须支付最低费用以进行集成。重要的是,我需要知道密钥是调试还是发布,而不知道密钥是什么。 - Fuzzical Logic
是的,这种方法只能在个人使用时使用,似乎不是很好的答案。 - xtr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接