有没有办法检查应用签名是调试还是发布?

Posted

技术标签:

【中文标题】有没有办法检查应用签名是调试还是发布?【英文标题】:Is there a way to check if an app signature is debug or published? 【发布时间】:2011-05-07 06:13:33 【问题描述】:

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

这样做的目的是能够判断他们的应用何时处于开发或发布状态,因为我需要能够判断他们应该访问我的开发服务器还是我的生产服务器。

【问题讨论】:

你们俩都提供了一些非常有用的信息。投票赞成两个答案。 【参考方案1】:

默认情况下,Eclipse 使用的 androiddebugkey(例如)有一个 notAfter 日期和时间,最多在未来 1 年 - Android 市场不接受这样一个短值 - 您可以使用它来区分在开发人员签名的版本之间?或者..您可以只检查应用使用的公钥 - 让他们使用应用的 android.content.pm.Signature 对 RPC 请求进行签名?

PackageInfo pkgInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES); 对于(签名appSignature:pkgInfo.signatures) // javax.security - 不是 java.security! X509Certificate appCertificate = X509Certificate.getInstance(appSignature.toByteArray()); // appCertificate.getNotAfter() 可以为您提供证书过期的日期和时间 // appCertificate.getPublicKey() 可以为您提供用于签署 RPC 请求的公钥。 // appCertificate.getSubjectDN() 将为您提供一个名为“CN=Android Debug,O=Android,C=US”的主体,用于任何未经开发人员手工制作的调试证书。

【讨论】:

感谢您的帮助!时间太长了,我几乎要放弃了。这里的问题是密钥“默认”为 1 年。我已经设置了 25 年的调试密钥……这就是为什么我需要能够分辨出差异的原因。有什么想法吗? 我认为这是正确的轨道。 getSubjectDN() 绝对是一种可能性。你能告诉我你是在哪里找到这些信息的,所以我可以进一步研究一下吗? 在使用此指南进行进一步研究后,我想出了一个有效的解决方案。它是多部分的,但要考虑尽可能多的情况。首先是检查日期。然后,SubjectDN。最后,在另一次失败时,我将公钥与市场查询匹配。当然,甚至没有接近完整的解决方案,但可以满足我的大部分需求。再次感谢您提供这么棒的信息。 是的,不幸的是,人们调整他们的密钥是很常见的(至少在第一个过期的混乱之后) - 或者更糟糕的是,将生产密钥推入他们的调试密钥库(.. 可怕的想法)。【参考方案2】:
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”,它会返回一个大的十六进制编码字符串。 静态最终字符串 DEBUGKEY = "key"; 这行似乎暗示我已经知道调试密钥,对吗?如果我是,我不可能知道调试密钥,因为它是由另一个开发人员提供的。我的 API 的工作方式是,对于调试应用程序,它可以免费用于测试,但对于已发布的应用程序,开发人员必须支付最低的集成费用。在不知道密钥是什么的情况下,我必须知道密钥是调试还是发布。 是的,这种方式只有在你个人使用并且看起来不好回答的情况下才能使用。

以上是关于有没有办法检查应用签名是调试还是发布?的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse Android 应用程序:使用真实证书签名运行

如何对Android的APP进行签名

Appium (Android):应用程序未使用调试证书签名

如何在没有任何签名的情况下使用已处理的应用程序运行 Wear 应用程序?我的意思是开发人员调试模式

有没有办法在 Python 中检查函数的签名?

有没有办法以编程方式获取应用程序的当前代码签名身份和/或配置文件?