128 votes

Comment vérifier si l'APK est signé ou s'il s'agit d'une "debug build" ?

Pour autant que je sache, dans Android, "release build" est signé APK. Comment le vérifier ? du code ou est-ce qu'Eclipse a une sorte de définition secrète ?

J'en ai besoin pour déboguer le remplissage des éléments d'une ListView à partir des données d'un service web (non, logcat n'est pas une option).

Ce que j'en pense :

  • L'application android:debuggable mais pour une raison ou une autre, cela ne semble pas fiable.
  • Le codage en dur de l'ID de l'appareil n'est pas une bonne idée, car j'utilise le même appareil pour tester les APK signés.
  • Utilisation d'un drapeau manuel quelque part dans le code ? C'est plausible, mais on oubliera certainement de le changer à un moment ou à un autre, et tous les programmeurs sont paresseux.

0 votes

Reprise de l'édition de Phil. Il ne s'agit pas de savoir si le programme est distribué légalement sur le marché ou non. Il s'agit de savoir si le programme est toujours en "mode débogage".

0 votes

Cette méthode est la plus simple : stackoverflow.com/a/23844716/2296787

139voto

Blundell Points 28342

Pour vérifier l'indicateur de débogage, vous pouvez utiliser ce code :

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

Kotlin :

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

Pour plus d'informations, voir Sécurisation des applications Android LVL .

Alternativement, si vous utilisez Gradle correctement, vous pouvez vérifier si BuildConfig.DEBUG est vrai ou faux.

0 votes

Il semble que cela vérifie toujours le manifest's Android:debuggable

2 votes

La première teste la possibilité de déboguer le manifeste, ce qui est obsolète. La seconde n'est pas possible pour les bibliothèques, la librairie aura sa propre BuildConfig - ne pouvant pas importer la BuildConfig de l'application qui utilise la librairie. La réponse marquée est donc "ok"

0 votes

Cette réponse fonctionnera dans tous les cas, quel que soit le projet de bibliothèque ou le projet d'application.

82voto

Omar Rehman Points 1042

Il existe différentes façons de vérifier si l'application est construite avec un certificat debug ou release, mais la méthode suivante me semble la meilleure.

D'après les informations contenues dans la documentation d'Android Signature de la demande La clé de débogage contient le nom distinctif suivant : " CN=Android Debug,O=Android,C=US ". Nous pouvons utiliser cette information pour tester si le paquet est signé avec la clé de débogage sans coder en dur la signature de la clé de débogage dans notre code.

Compte tenu de ce qui précède :

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

Vous pouvez implémenter une méthode isDebuggable de cette manière :

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;
}

6 votes

Pour faciliter la résolution des correspondances d'importations multiples, les classes utilisées ici sont les suivantes java.security.cert.X509Certificate , java.security.cert.CertificateException y android.content.pm.Signature . Toutes les autres classes ne présentent pas de correspondance multiple pour moi.

1 votes

Réponse éditée avec ces importations. Merci de votre compréhension.

0 votes

Est-il suffisamment efficace pour être exécuté dans la méthode onCreate de la classe d'application ?

28voto

Heath Borders Points 8067

Si vous souhaitez vérifier un APK statiquement, vous pouvez utiliser

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

Cette sortie 0 si le APK n'est pas débogable et 1 si c'est le cas.

3 votes

C'est la seule solution, pour vérifier par dessus l'apk final. Les autres réponses supposent que vous avez la source.

1 votes

aapt vit ici /Users/USER_NAME/library/Android/sdk/build-tools/28.0.3/aapt

22voto

urSus Points 2583

Peut-être en retard, mais l'utilisation de l'iosched BuildConfig.DEBUG

0 votes

Est-ce qu'il peut être utilisé en toute sécurité ? Il y a un article qui dit qu'il y a des problèmes : digipom.com/be-careful-with-buildconfig-debug (en anglais)

0 votes

C'est la meilleure réponse !

0 votes

Pas si vous écrivez une bibliothèque tierce et que vous ne connaissez pas le paquetage de BuildConfig au moment de la compilation.

5voto

Nikolay Elenkov Points 32843

Une version de débogage est également signée, mais avec une clé différente. Elle est générée automatiquement par Eclipse, et son certificat n'est valable qu'un an. Quel est le problème avec android:debuggable ? Vous pouvez obtenir cette valeur à partir du code en utilisant PackageManager .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X