How to check if APK is signed or “debug build”?

后端 未结 10 1902
我在风中等你
我在风中等你 2020-11-29 16:34

As far as I know, in android \"release build\" is signed APK. How to check it from code or does Eclipse has some kinda of secret defines?

I need thi

相关标签:
10条回答
  • 2020-11-29 16:40

    There are different way to check if the application is build using debug or release certificate, but the following way seems best to me.

    According to the info in Android documentation Signing Your Application, debug key contain following subject distinguished name: "CN=Android Debug,O=Android,C=US". We can use this information to test if package is signed with debug key without hardcoding debug key signature into our code.

    Given:

    import android.content.pm.Signature;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    

    You can implement an isDebuggable method this way:

    private static final X500Principal DEBUG_DN = new X500Principal("CN=Android Debug,O=Android,C=US");
    private boolean isDebuggable(Context ctx)
    {
        boolean debuggable = false;
    
        try
        {
            PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),PackageManager.GET_SIGNATURES);
            Signature signatures[] = pinfo.signatures;
    
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
    
            for ( int i = 0; i < signatures.length;i++)
            {   
                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)
        {
            //debuggable variable will remain false
        }
        catch (CertificateException e)
        {
            //debuggable variable will remain false
        }
        return debuggable;
    }
    
    0 讨论(0)
  • 2020-11-29 16:46

    Solution in Kotlin that I'm using at the moment:

    @SuppressLint("PackageManagerGetSignatures")
    @Suppress("DEPRECATION")
    fun isSigned(context: Context?): Boolean {
        return (context?.packageManager?.getPackageInfo(context.packageName, PackageManager.GET_SIGNATURES)?.signatures?.firstOrNull()?.toByteArray()
                ?.let {
                    return@let CertificateFactory.getInstance("X.509").generateCertificate(ByteArrayInputStream(it))
                } as? X509Certificate)
                ?.issuerDN
                ?.name
                ?.contains("O=Android", ignoreCase = false) ?: true
    }
    

    that way I can still SIGN in debug and those will be reported to Crashlytics (example, for the QA process)

    0 讨论(0)
  • 2020-11-29 16:47

    Maybe late, but iosched uses BuildConfig.DEBUG

    0 讨论(0)
  • 2020-11-29 16:50

    To check the debuggable flag, you can use this code:

    boolean isDebuggable =  ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
    

    Kotlin:

    val isDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
    

    For more information, please see Securing Android LVL Applications.

    Alternatively, if you're using Gradle correctly, you can check if BuildConfig.DEBUG is true or false.

    0 讨论(0)
  • 2020-11-29 16:50

    A debug build is signed as well, just with a different key. It's generated automatically by Eclipse, and its certificate is valid for one year only. What's the problem with android:debuggable? You can get this value from code using PackageManager.

    0 讨论(0)
  • 2020-11-29 16:51

    If you want to check an APK statically, you could use

    aapt dump badging /path/to/apk | grep -c application-debuggable
    

    This outputs 0 if the APK isn't debuggable and 1 if it is.

    0 讨论(0)
提交回复
热议问题