Google Play 서비스에서 제공하는 라이브러리인 SafetyNet Verify Apps API를 사용하면 앱이 기기의 앱 인증 기능과 프로그래매틱 방식으로 상호작용할 수 있어 잠재적으로 위험한 앱으로부터 기기를 보호합니다.
앱에서 금융 정보와 같은 민감한 사용자 데이터를 처리하는 경우 사용자의 기기가 악성 앱으로부터 보호되고 있으며 내 앱을 가장하거나 다른 악성 작업을 실행할 수 있는 앱이 없는지 확인하는 것이 중요합니다. 기기의 보안이 최소 보안 상황을 충족하지 않으면 자체 앱 내에서 기능을 사용 중지하여 사용자에게 미치는 위험을 줄일 수 있습니다.
Google은 Android 생태계를 최대한 안전하게 만들려는 지속적인 노력의 일환으로 Android 앱의 동작을 모니터링하고 프로파일링합니다. 앱 인증 기능이 잠재적으로 위험한 앱을 감지하면 이 앱을 설치한 모든 사용자는 앱을 즉시 제거하라는 알림을 받습니다. 이 프로세스는 이러한 사용자의 보안 및 개인 정보 보호를 강화합니다.
SafetyNet Verify Apps API를 사용하면 이 기능을 활용하여 앱의 데이터를 보호할 수 있습니다. 이 API를 사용하면 사용자의 기기가 앱 인증 기능으로 보호되는지 여부를 확인하고, 이 기능을 아직 사용하지 않는 사용자에게 이 기능의 보호를 선택하도록 권장하고, 기기에 설치되어 있는 알려진 잠재적으로 위험한 앱을 식별할 수 있습니다.
추가 서비스 약관
SafetyNet API에 액세스하거나 SafetyNet API를 사용하면 Google API 서비스 약관 및 다음 Verify Apps API 서비스 약관에 동의하는 것으로 간주됩니다. SafetyNet API에 액세스하기 전에 모든 관련 약관 및 정책을 자세히 읽고 숙지하시기 바랍니다.
Verify Apps API 서비스 약관
잠재적으로 위험한 앱을 식별하는 앱을 분석하면 결과에 거짓양성과 거짓음성이 모두 나올 수 있습니다. 이 API 세트에서 반환된 결과(또는 결과 없음)는 Google이 파악한 한도 내에서 제시됩니다. 개발자는 이 SafetyNet API 세트에서 반환되는 결과가 때로는 정확성이 보장되지 않는다는 점을 인정하고 이해합니다.SafetyNet API 종속 항목 추가
Verify Apps API를 사용하기 전에 프로젝트에 SafetyNet API를 추가하세요. Android 스튜디오를 사용한다면 이 종속 항목을 앱 수준 Gradle 파일에 추가하세요. 자세한 내용은 SafetyNet API 설정을 참고하세요.
앱 인증 사용 설정
SafetyNet Verify Apps API에는 앱 인증 기능을 사용 설정하는 두 가지 방법이 있습니다. isVerifyAppsEnabled()
를 사용하여 앱 인증이 사용 설정되어 있는지 여부를 확인할 수 있으며 enableVerifyApps()
를 사용하여 앱 인증 사용 설정을 요청할 수 있습니다.
이 두 가지 방법의 차이를 보면, isVerifyAppsEnabled()
는 앱 인증 기능의 현재 상태를 보고하고 enableVerifyApps()
는 사용자에게 앱 인증 기능 사용에 동의하도록 명시적으로 요청합니다. 앱이 보안 기반 결정을 내리기 위해 앱 인증 기능의 상태를 인지하도록 하려면 앱이 isVerifyAppsEnabled()
를 호출해야 합니다. 그러나 앱이 기기에 설치되어 잠재적으로 위험한 앱을 나열할 수 있게 하려면 enableVerifyApps()
를 대신 호출해야 합니다.
앱 인증이 사용 설정되었는지 여부 확인
비동기 isVerifyAppsEnabled()
메서드를 사용하면 사용자가 앱 인증 기능에 등록되었는지 앱에서 확인할 수 있습니다. 이 메서드는 VerifyAppsUserResponse
객체를 반환하며, 이 객체에는 사용자가 앱 인증 기능과 관련하여 취한 모든 조치(사용 설정 포함)에 관한 정보가 포함되어 있습니다.
다음 코드 스니펫은 이 메서드와 관련된 콜백을 만드는 방법을 보여줍니다.
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()
메서드를 사용하면 앱에서 사용자에게 앱 인증 기능을 사용 설정하도록 요청하는 대화상자를 호출할 수 있습니다. 이 메서드는 VerifyAppsUserResponse
객체를 반환하며, 이 객체에는 사용자가 앱 인증 기능과 관련하여 취한 모든 조치(사용 설정하도록 동의했는지 여부 포함)에 관한 정보가 포함되어 있습니다.
다음 코드 스니펫은 이 메서드와 관련된 콜백을 만드는 방법을 보여줍니다.
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는 사용자가 이 기능을 사용 설정하도록 동의한 것처럼 작동합니다.
- 사용자가 대화상자에서 벗어나서 이동하면 대화상자가 사라지고 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." ) } }
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."); } } });