SafetyNet Verify Apps API

SafetyNet Verify Apps API를 사용하면 프로그래밍 방식으로 앱이 기기의 앱 인증 기능과 상호작용하여 잠재적으로 위험한 앱으로부터 기기를 보호할 수 있습니다.

앱이 재무 정보 같은 민감한 사용자 데이터를 처리한다면 현재 기기가 악성 앱으로부터 보호되는지 그리고 현재 기기에 악성 앱을 사칭하거나 다른 악의적인 작업을 수행하는 앱이 없는지 확인해야 합니다. 기기의 보안이 최소 보안 요건을 충족하지 않으면 고유 앱 내의 기능을 사용 중지하여 사용자에게 미치는 위험을 줄일 수 있습니다.

Google은 Android 생태계를 최대한 안전하게 만들려는 지속적인 노력의 일환으로 Android 앱의 동작을 모니터링하고 프로파일링합니다. 앱 인증 기능이 잠재적으로 위험한 앱을 감지하면 이 앱을 설치한 모든 사용자는 앱을 즉시 제거하라는 알림을 받습니다. 이 프로세스는 이러한 사용자의 보안 및 개인정보 보호를 보호합니다.

SafetyNet Verify Apps API를 사용하면 앱 인증 기능을 활용해 앱의 데이터를 보호할 수 있습니다. 이 API를 사용하면 사용자의 기기가 앱 인증 기능으로 보호되는지 여부를 확인하고, 이 기능을 아직 사용하지 않는 사용자에게 이 기능의 보호를 선택하도록 권장하고, 기기에 설치되어 있는 잠재적으로 위험한 알려진 앱을 식별할 수 있습니다.

주의: SafetyNet이 사용자에게 잠재적으로 위험 앱을 알리지만 일부 사용자는 이 앱을 제거하지 않기로 선택할 수도 있고 경고 알림을 보지 못할 수도 있습니다. 따라서 기기에 앱 인증 기능이 사용 설정되어 있어도 잠재적으로 위험한 앱이 있을 수 있습니다.

추가 서비스 약관

SafetyNet API를 액세스하거나 사용하면 Google API 서비스 약관 및 이 추가 약관에 동의하는 것으로 간주됩니다. SafetyNet API에 액세스하기 전에 모든 관련 약관 및 정책을 자세히 읽고 숙지하시기 바랍니다.

Verify Apps API 서비스 약관

잠재적으로 위험한 앱을 식별하는 앱을 분석하면 결과에 거짓양성과 거짓음성이 모두 나올 수 있습니다. 이 API 세트에서 반환된 결과(또는 결과 없음)는 Google이 파악한 한도 내에서 제시됩니다. 개발자는 이 SafetyNet API 세트에서 반환되는 결과가 때로는 정확성이 보장되지 않는다는 점을 인정하고 이해합니다.

앱 인증 사용 설정하기

SafetyNet Verify Apps API에는 앱 인증 기능을 사용 설정하는 두 가지 방법이 있습니다. isVerifyAppsEnabled()를 사용하여 앱 인증이 사용 설정되어 있는지 여부를 확인할 수 있으며 enableVerifyApps()를 사용하여 앱 인증 사용 설정을 요청할 수 있습니다.

이 두 가지 방법의 차이를 보면, 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.")
                }
            }
    

자바

    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.")
                }
            }
    

자바

    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는 사용자가 이 기능을 사용 설정하도록 동의한 것처럼 작동합니다.
  • 사용자가 대화상자에서 벗어나서 이동하면 대화상자가 사라지고 API는 사용자가 이 기능을 사용 설정하도록 동의하지 않았다고 가정합니다.
  • 개발자의 앱 및 다른 앱이 동시에 이 메서드를 호출하면 대화상자가 한 개만 나타나고 모든 앱이 메서드에서 동일한 반환 값을 수신합니다.

설치되어 있는 잠재적으로 위험한 앱 나열하기

비동기 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."
                    )
                }
            }
    

자바

    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.");
                }
            }
        });