SafetyNet 安全浏览 API

SafetyNet 安全浏览 API 是一个由 Google Play 服务 提供支持的库,它提供服务来确定 Google 是否已将某个网址标记为已知威胁。

您的应用可以使用此 API 来确定 Google 是否已将特定网址归类为已知威胁。在内部,SafetyNet 实现了一个 Google 开发的安全浏览网络协议 v4 的客户端。客户端代码和 v4 网络协议均旨在保护用户的隐私,并最大限度地减少电池和带宽消耗。使用此 API 以最优化的方式充分利用 Google 的安全浏览服务,而无需实现其网络协议。

本文档说明如何使用 SafetyNet 安全浏览查找 API 检查网址是否存在已知威胁。

服务条款

使用安全浏览 API 即表示您同意受 服务条款 的约束。在访问安全浏览 API 之前,请阅读并理解所有适用的条款和政策。

请求和注册 Android API 密钥

在使用安全浏览 API 之前,请创建并注册 Android API 密钥。有关具体步骤,请参阅关于 安全浏览入门 的页面。

添加 SafetyNet API 依赖项

在使用安全浏览 API 之前,请将 SafetyNet API 添加到您的项目中。如果您使用的是 Android Studio,请将此依赖项添加到您的应用级 Gradle 文件中。有关详细信息,请参阅 使用 SafetyNet 防范安全威胁

初始化 API

要使用安全浏览 API,必须通过调用 initSafeBrowsing() 并等待其完成来初始化 API。以下代码片段提供了一个示例

Kotlin

Tasks.await(SafetyNet.getClient(this).initSafeBrowsing())

Java

Tasks.await(SafetyNet.getClient(this).initSafeBrowsing());

请求网址检查

您的应用可以使用网址检查来确定某个网址是否构成已知威胁。某些威胁类型可能与您的特定应用无关。API 允许您选择对您的需求至关重要的威胁类型。您可以指定多种已知威胁类型。

发送网址检查请求

API 与使用的方案无关,因此您可以使用或不使用方案传递网址。例如,两者

Kotlin

var url = "https://www.google.com"

Java

String url = "https://www.google.com";

Kotlin

var url = "www.google.com"

Java

String url = "www.google.com";

都是有效的。

以下代码演示如何发送网址检查请求

Kotlin

SafetyNet.getClient(this).lookupUri(
       url,
       SAFE_BROWSING_API_KEY,
       SafeBrowsingThreat.TYPE_POTENTIALLY_HARMFUL_APPLICATION,
       SafeBrowsingThreat.TYPE_SOCIAL_ENGINEERING
)
       .addOnSuccessListener(this) { sbResponse ->
           // Indicates communication with the service was successful.
           // Identify any detected threats.
           if (sbResponse.detectedThreats.isEmpty()) {
               // No threats found.
           } else {
               // Threats found!
           }
       }
       .addOnFailureListener(this) { e: Exception ->
           if (e is ApiException) {
               // An error with the Google Play Services API contains some
               // additional details.
               Log.d(TAG, "Error: ${CommonStatusCodes.getStatusCodeString(e.statusCode)}")

               // Note: If the status code, s.statusCode,
               // is SafetyNetStatusCode.SAFE_BROWSING_API_NOT_INITIALIZED,
               // you need to call initSafeBrowsing(). It means either you
               // haven't called initSafeBrowsing() before or that it needs
               // to be called again due to an internal error.
           } else {
               // A different, unknown type of error occurred.
               Log.d(TAG, "Error: ${e.message}")
           }
       }

Java

SafetyNet.getClient(this).lookupUri(url,
         SAFE_BROWSING_API_KEY,
         SafeBrowsingThreat.TYPE_POTENTIALLY_HARMFUL_APPLICATION,
         SafeBrowsingThreat.TYPE_SOCIAL_ENGINEERING)
   .addOnSuccessListener(this,
       new OnSuccessListener<SafetyNetApi.SafeBrowsingResponse>() {
           @Override
           public void onSuccess(SafetyNetApi.SafeBrowsingResponse sbResponse) {
               // Indicates communication with the service was successful.
               // Identify any detected threats.
               if (sbResponse.getDetectedThreats().isEmpty()) {
                   // No threats found.
               } else {
                   // Threats found!
               }
        }
   })
   .addOnFailureListener(this, new OnFailureListener() {
           @Override
           public void onFailure(@NonNull Exception e) {
               // An error occurred while communicating with the service.
               if (e instanceof ApiException) {
                   // An error with the Google Play Services API contains some
                   // additional details.
                   ApiException apiException = (ApiException) e;
                   Log.d(TAG, "Error: " + CommonStatusCodes
                       .getStatusCodeString(apiException.getStatusCode()));

                   // Note: If the status code, apiException.getStatusCode(),
                   // is SafetyNetStatusCode.SAFE_BROWSING_API_NOT_INITIALIZED,
                   // you need to call initSafeBrowsing(). It means either you
                   // haven't called initSafeBrowsing() before or that it needs
                   // to be called again due to an internal error.
               } else {
                   // A different, unknown type of error occurred.
                   Log.d(TAG, "Error: " + e.getMessage());
               }
           }
   });

读取网址检查响应

使用返回的 SafetyNetApi.SafeBrowsingResponse 对象,调用其 getDetectedThreats() 方法,该方法返回 SafeBrowsingThreat 对象列表。如果返回的列表为空,则 API 未检测到任何已知威胁。如果列表不为空,请在列表中的每个元素上调用 getThreatType() 来确定 API 检测到的已知威胁。

要查看建议的警告语言,请参阅 安全浏览 API 开发人员指南

指定感兴趣的威胁类型

SafeBrowsingThreat 类中的常量包含当前支持的威胁类型

威胁类型 定义
潜在有害应用类型 此威胁类型标识已标记为包含潜在有害应用程序的页面网址。
社交工程类型 此威胁类型标识已标记为包含社交工程威胁的页面网址。

使用 API 时,您需要将威胁类型常量作为参数添加。您可以根据应用需求添加任意数量的威胁类型常量,但只能使用未标记为已弃用的常量。

关闭您的安全浏览会话

如果您的应用不需要长时间使用安全浏览 API,请检查应用中的所有必要网址,然后使用shutdownSafeBrowsing()方法关闭您的安全浏览会话。

Kotlin

SafetyNet.getClient(this).shutdownSafeBrowsing()

Java

SafetyNet.getClient(this).shutdownSafeBrowsing();

我们建议您在 activity 的onPause()方法中调用shutdownSafeBrowsing(),并在 activity 的onResume()方法中调用initSafeBrowsing()。但是,请确保initSafeBrowsing()执行完毕后再调用lookupUri()。通过确保您的会话始终保持最新状态,您可以降低应用内部错误的可能性。

SafetyNet 安全浏览 API 收集的数据

SafetyNet 安全浏览 API 在与 Android 上的安全浏览服务通信时会自动收集以下数据。

数据 描述
应用活动 在本地哈希前缀匹配后收集网址的哈希前缀,用于检测恶意网址。

虽然我们力求尽可能透明,但您应对如何回应Google Play 的数据安全部分表格(关于您应用的用户数据收集、共享和安全实践)负全部责任。