web-dev-qa-db-ja.com

APKが署名されているか「デバッグビルド」されているかどうかを確認する方法

私の知る限り、Androidの「リリースビルド」にはAPKが署名されています。それを確認する方法コードからまたは、Eclipseには何らかの秘密の定義がありますか?

これは、WebサービスデータからListViewアイテムの生成をデバッグするために必要です(logcatはオプションではありません)。

私の考え:

  • アプリケーションのAndroid:debuggableですが、何らかの理由で信頼性がありません。
  • 署名済みAPKのテストに同じデバイスを使用しているため、デバイスIDをハードコーディングすることはお勧めできません。
  • コードのどこかに手動フラグを使用していますか?もっともらしいが、いつか変更することを間違いなく忘れるだろうし、プラスすべてのプログラマーは怠け者だ。
114
Im0rtality

デバッグ証明書またはリリース証明書を使用してアプリケーションがビルドされているかどうかを確認する別の方法がありますが、次の方法が最適です。

Android documentation Signing Your Application の情報によると、デバッグキーには次のサブジェクト識別名が含まれています: "CN = Android Debug、O = Android 、C = US」。この情報を使用して、デバッグキー署名をコードにハードコーディングせずに、パッケージがデバッグキーで署名されているかどうかをテストできます。

与えられた:

import Android.content.pm.Signature;
import Java.security.cert.CertificateException;
import Java.security.cert.X509Certificate;

この方法でisDebuggableメソッドを実装できます。

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;
}
76
Omar Rehman

デバッグ可能フラグを確認するには、次のコードを使用できます。

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

コトリン:

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

詳細については、 Securing Android LVL Applications をご覧ください。

あるいは、Gradleを正しく使用している場合は、BuildConfig.DEBUGがtrueまたはfalseであるかどうかを確認できます。

135
Blundell

マーク・マーフィーによる回答

最も簡単な、そして最善の長期的な解決策BuildConfig.DEBUGを使用することです。これは、デバッグビルドの場合はbooleanになるtrue値です。それ以外の場合はfalseです。

if (BuildConfig.DEBUG) {
  // do something for a debug build
}
130
Xar E Ahmer

遅れるかもしれませんが、ioschedはBuildConfig.DEBUGを使用します

21
urSus

APKを静的にチェックする場合は、次を使用できます。

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

これは、APKがデバッグ可能でない場合は0を出力し、デバッグ可能な場合は1を出力します。

19
Heath Borders

まず、これをbuild.gradleファイルに追加します。これにより、デバッグビルドとリリースビルドのサイドバイサイド実行も可能になります。

buildTypes {
    debug {
        applicationIdSuffix ".debug"
    }
}

このメソッドを追加します。

public static boolean isDebug(Context context) {
    String pName = context.getPackageName();
    if (pName != null && pName.endsWith(".debug")) {
        return true;
    } else {
        return false;
    }
}
10
Meanman

デバッグビルドも別のキーで署名されます。 Eclipseによって自動的に生成され、その証明書は1年間のみ有効です。 Android:debuggableの問題は何ですか?この値は、PackageManagerを使用してコードから取得できます。

5
Nikolay Elenkov

言及する価値がある別のオプション。デバッガーが接続されているときにのみコードを実行する必要がある場合は、次のコードを使用します。

if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { 
    //code to be executed 
}
3
Igor Gorjanc

現在使用しているKotlinのソリューション:

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

そうすれば、デバッグでまだ署名することができ、それらはCrashlyticsに報告されます(QAプロセスの場合など)

0

Android:debuggableで解決しました。アイテムのデバッグフラグは、アイテムのデバッグフラグがif (m.debug && !App.isDebuggable(getContext()))が常にfalseに評価されるレコードに保存されない場合があるバグでした。私の悪い。

0
Im0rtality