The Android Developer Challenge is back! Submit your idea before December 2.

SafetyNet Verify Apps API

SafetyNet Verify Apps API を使用すると、アプリが、アプリの確認機能とプログラムでやり取りし、有害な可能性があるアプリからデバイスを保護できます。

アプリが財務情報などの重要なユーザーデータを扱う場合、現在のデバイスが悪意のあるアプリから保護されており、現在のデバイスになりすましなどの悪意のあるアクションを実行するアプリがないことを確認する必要があります。デバイスのセキュリティが最低限のセキュリティ態勢を満たしていない場合は、お客様のアプリ内の機能を無効にして、ユーザーへの危険を減らすことができます。

Google は、Android エコシステムを可能な限り安全にするという継続的な取り組みの一環として、Android アプリの動作を監視および鑑定します。アプリの確認機能で有害な可能性があるアプリが検出されると、アプリをインストールしたすべてのユーザーに通知され、すぐにアプリをアンインストールするように促されます。このプロセスにより、ユーザーのセキュリティとプライバシーが保護されます。

SafetyNet Verify Apps API を使用すると、この機能を活用してアプリのデータを保護できます。この API を使用すると、ユーザーのデバイスがアプリの確認機能で保護されているかどうかを判定し、この機能を使用していないユーザーにデバイスの保護をオプトインするように促すことにより、デバイスにインストールされている既知の有害な可能性があるアプリを特定できます。

注意: SafetyNet は有害な可能性があるアプリをユーザーに通知しますが、ユーザーがアプリをアンインストールしない場合や、警告通知が表示されない場合があります。そのため、アプリの確認機能が有効になっていても、有害な可能性があるアプリがインストールされている可能性があります。

追加利用規約

SafetyNet API にアクセス、またはこれを使用すると、Google API 利用規約と追加規約に同意したことになります。適用されるすべての利用規約とポリシーを確認し理解したうえで API にアクセスしてください。

Verify Apps API 利用規約

有害な可能性があるアプリを特定するアプリの分析では、偽陽性と偽陰性の両方が発生する可能性があります。この API スイートが返す結果(またはその欠如)は、把握できる限りの提示がされています。お客様は、この SafetyNet API スイートによって返される結果が常に正確であるとは限らないことを了承し、理解するものとします。

アプリの確認を有効にする

SafetyNet Verify Apps API には、アプリの確認機能の有効化に関する 2 つのメソッドがあります。isVerifyAppsEnabled() を使用するとアプリの確認が有効になっているかどうかを判定でき、enableVerifyApps() を使用するとアプリの確認の有効化をリクエストできます。

2 つのメソッドの違いは、isVerifyAppsEnabled()アプリの確認機能の現行ステータスを報告するのに対して、enableVerifyApps() はユーザーに対してこの機能を使用する許可を明示的に求めることです。セキュリティに基づく決定をするために、アプリでこの機能のステータスを知る必要があるだけの場合は、isVerifyAppsEnabled() を呼び出す必要があります。これに対して、アプリで有害な可能性があるアプリを列挙できるようにするには、enableVerifyApps() を呼び出す必要があります。

アプリの確認が有効になっているかどうかを確認する

非同期の isVerifyAppsEnabled() メソッドを使用すると、ユーザーがアプリの確認機能に登録されているかどうかアプリで判断できます。このメソッドは VerifyAppsUserResult オブジェクトを返します。このオブジェクトには、アプリの確認機能に関連する、有効化などのすべてのアクションに関する情報が含まれています。

このメソッドに関連付けられたコールバックを作成する方法を、次のコード スニペットに示します。

Kotlin

    SafetyNet.getClient(this)
            .isVerifyAppsEnabled
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    if (task.result.isVerifyAppsEnabled) {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.")
                    } else {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.")
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.")
                }
            }
    

Java

    SafetyNet.getClient(this)
        .isVerifyAppsEnabled()
        .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
            @Override
            public void onComplete(Task<VerifyAppsUserResponse> task) {
                if (task.isSuccessful()) {
                    VerifyAppsUserResponse result = task.getResult();
                    if (result.isVerifyAppsEnabled()) {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is enabled.");
                    } else {
                        Log.d("MY_APP_TAG", "The Verify Apps feature is disabled.");
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.");
                }
            }
        });
    

アプリの確認の有効化をリクエストする

非同期の enableVerifyApps() メソッドを使用すると、ユーザーがアプリの確認機能を有効にするようリクエストするダイアログをアプリから呼び出すことができます。このメソッドは VerifyAppsUserResult オブジェクトを返します。このオブジェクトには、ユーザーが有効化に同意したかなどの、アプリの確認機能に関連するすべてのアクションに関する情報が含まれています。

このメソッドに関連付けられたコールバックを作成する方法を、次のコード スニペットに示します。

Kotlin

    SafetyNet.getClient(this)
            .enableVerifyApps()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    if (task.result.isVerifyAppsEnabled) {
                        Log.d("MY_APP_TAG", "The user gave consent to enable the Verify Apps feature.")
                    } else {
                        Log.d(
                                "MY_APP_TAG",
                                "The user didn't give consent to enable the Verify Apps feature."
                        )
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.")
                }
            }
    

Java

    SafetyNet.getClient(this)
        .enableVerifyApps()
        .addOnCompleteListener(new OnCompleteListener<VerifyAppsUserResponse>() {
            @Override
            public void onComplete(Task<VerifyAppsUserResponse> task) {
                if (task.isSuccessful()) {
                    VerifyAppsUserResponse result = task.getResult();
                    if (result.isVerifyAppsEnabled()) {
                        Log.d("MY_APP_TAG", "The user gave consent " +
                              "to enable the Verify Apps feature.");
                    } else {
                        Log.d("MY_APP_TAG", "The user didn't give consent " +
                              "to enable the Verify Apps feature.");
                    }
                } else {
                    Log.e("MY_APP_TAG", "A general error occurred.");
                }
            }
        });
    

このメソッドを使用するとき、次のような例外的な状況に遭遇する可能性があります。

  • アプリの確認機能がすでに有効になっている場合、ダイアログは表示されず、ユーザーがこの機能の有効化に同意したかのように動作します。
  • ユーザーがダイアログから移動した場合、ダイアログは破棄され、API はユーザーがこの機能の有効化に同意しなかったと見なします。
  • お客様のアプリと別のアプリが同時にこのメソッドを呼び出した場合、ダイアログは 1 つだけ表示され、どちらのアプリも同じ戻り値をメソッドから受け取ります。

有害な可能性があるインストール済みアプリを列挙する

非同期の listHarmfulApps() メソッドを使用すると、デバイスにインストールしている既知の有害な可能性があるアプリのリストをユーザーが取得できます。このリストには、アプリが適切な対応をとれるように、特定された有害な可能性があるアプリのカテゴリが含まれています。

このメソッドに関連付けられたコールバックを作成する方法を、次のコード スニペットに示します。

Kotlin

    SafetyNet.getClient(this)
            .listHarmfulApps()
            .addOnCompleteListener { task ->
                Log.d(TAG, "Received listHarmfulApps() result")

                if (task.isSuccessful) {
                    val result = task.result
                    val scanTimeMs = result.lastScanTimeMs

                    val appList = result.harmfulAppsList
                    if (appList?.isNotEmpty() == true) {
                        Log.e("MY_APP_TAG", "Potentially harmful apps are installed!")

                        for (harmfulApp in appList) {
                            Log.e("MY_APP_TAG", "Information about a harmful app:")
                            Log.e("MY_APP_TAG", "  APK: ${harmfulApp.apkPackageName}")
                            Log.e("MY_APP_TAG", "  SHA-256: ${harmfulApp.apkSha256}")

                            // Categories are defined in VerifyAppsConstants.
                            Log.e("MY_APP_TAG", "  Category: ${harmfulApp.apkCategory}")
                        }
                    } else {
                        Log.d("MY_APP_TAG", "There are no known potentially harmful apps installed.")
                    }
                } else {
                    Log.d(
                            "MY_APP_TAG",
                            "An error occurred. Call isVerifyAppsEnabled() to ensure that the user "
                                    + "has consented."
                    )
                }
            }
    

Java

    SafetyNet.getClient(this)
        .listHarmfulApps()
        .addOnCompleteListener(new OnCompleteListener<HarmfulAppsResponse>() {
            @Override
            public void onComplete(Task<HarmfulAppsResponse> task) {
                Log.d(TAG, "Received listHarmfulApps() result");

                if (task.isSuccessful()) {
                    HarmfulAppsResponse result = task.getResult();
                    long scanTimeMs = result.getLastScanTimeMs();

                    List<HarmfulAppsData> appList = result.getHarmfulAppsList();
                    if (appList.isEmpty()) {
                        Log.d("MY_APP_TAG", "There are no known " +
                              "potentially harmful apps installed.");
                    } else {
                        Log.e("MY_APP_TAG",
                              "Potentially harmful apps are installed!");

                        for (HarmfulAppsData harmfulApp : appList) {
                            Log.e("MY_APP_TAG", "Information about a harmful app:");
                            Log.e("MY_APP_TAG",
                                  "  APK: " + harmfulApp.apkPackageName);
                            Log.e("MY_APP_TAG",
                                  "  SHA-256: " + harmfulApp.apkSha256);

                            // Categories are defined in VerifyAppsConstants.
                            Log.e("MY_APP_TAG",
                                  "  Category: " + harmfulApp.apkCategory);
                        }
                    }
                } else {
                    Log.d("MY_APP_TAG", "An error occurred. " +
                          "Call isVerifyAppsEnabled() to ensure " +
                          "that the user has consented.");
                }
            }
        });