设备信任信号

Android 提供了各种设备信号,管理员可以使用这些信号来确定设备的安全状况。在零信任安全模型中,这些信号用于评估是否应允许设备访问公司信息。

功能 说明 全代管式设备 公司自有设备上的工作资料 个人设备 (BYOD) 上的工作资料 非受管设备
Play Integrity API 信任代理可以检索以下信号:
  • 设备完整性
  • 应用完整性
  • Play 许可详情
  • 环境详情,包括新的 Play 保护机制判定
  • 安全硬件存在 / 密钥认证 信任代理可以验证其 PKI 凭据是否已生成并存储在安全硬件中
    设备属性认证 在密钥认证过程中,可以将设备属性包含在认证记录中
    设备安全补丁级别 信任代理可以验证操作系统安全补丁级别
    设备是否有待处理的 OTA 信任代理可以检查是否有待处理的设备操作系统更新 不适用
    Mainline 安全补丁级别 信任代理可以读取已安装 Mainline 模块序列的安全补丁级别
    注册专用 ID 信任代理可以访问特定于该企业的唯一设备 ID。此 ID 在重新创建工作资料和恢复设备出厂设置后保持不变 不适用
    管理状态(以及管理应用) 信任代理可以使用此属性来确定设备是否受管理 不适用
    磁盘加密 信任代理可以检查设备是否已加密(如果需要 Android 8 支持)
    操作系统版本 信任代理可以检查设备操作系统版本,并确认其高于特定版本
    访问网络状态(网络状态和 Wi-Fi 状态) Trust 代理可以获取有关活跃网络状态(移动网络和 Wi-Fi)的信息
    访问 Wi-Fi 状态(Android 11 及更低版本,Android 12 及更高版本同时支持回调按需方法) 信任代理可以获取有关处于活动状态的 Wi-Fi 网络的信息
    代理设置 信任代理可以获取有关当前默认 HTTP 代理设置的信息。
    屏幕锁定安全系数检查 信任代理可以在授予访问权限之前确保设备配置了一定质量的屏幕锁定
    已启用开发者选项 当开发者选项处于启用状态时,信任代理可以将设备识别为具有更广泛的攻击面
    是否已启用 TLS 上的 DNS 信任代理可以利用此方法来确保启用专用 DNS 模式
    SafetyNet 安全浏览 信任代理可以确定某个特定网址是否已被 Google 归类为已知威胁。
    外部媒体挂载 在挂载外部存储空间时,可以通知信任代理
    UsageStatsManager 信任代理可以研究各个应用的使用模式 1
    安全日志记录 信任代理可以将这些数据作为其内容相关引擎的一部分来使用,以确保合规性并创建基于行为的指纹 2 2 不适用
    网络日志记录 信任代理可以将这些数据作为其内容相关引擎的一部分来使用,以确保合规性并创建基于行为的指纹 2 2 不适用
    NetworkStatsManager Trust 代理可以查询给定时间间隔内的应用网络使用情况 2 1
    软件包可见性(列出设备上的所有应用) 信任代理可以查询设备上安装了哪些应用 3 3
    读取手机状态 信任代理可以获取移动网络信息、任何正在进行的通话的状态,以及设备上注册的 PhoneAccount 列表
    设备上次重新启动的时间 信任代理可以获取系统正常运行时间
    获取账号 信任代理可以利用此权限访问账号服务中的账号列表 3 3 1
    监控显著的电池电量变化 信任代理可以监控电池电量出现的显著变化
    位置(精确、粗略等) 信任代理可以访问设备的实际位置 1 1

    1 征得用户同意

    2 仅限工作资料

    3 仅限于工作资料信息的访问权限

    信任代理可以访问 com.google.android.modulemetadata 模块的 PackageInfo,并从中检索 versionName

    private fun mainlineVersion(context: Context): String? {
        val moduleProvider = "com.google.android.modulemetadata"
    
        return try {
                val pm = context.packageManager
                val packageInfo = pm.getPackageInfo(moduleProvider, 0)
                packageInfo.versionName
            } catch (e: PackageManager.NameNotFoundException) {
                null
            }
    }
    

    您可以使用 SimpleDateFormat 类将返回的字符串解析为 Date 对象:

    private val VERSION_NAME_DATE_PATTERNS = Arrays.asList(
          "yyyy-MM-dd",
          "yyyy-MM"
    )
    
    private fun parseDateFromVersionName(text: String): Date? {
        for (pattern in VERSION_NAME_DATE_PATTERNS) {
            try {
                val simpleDateFormat = SimpleDateFormat(
                    pattern,
                    Locale.getDefault()
                )
                simpleDateFormat.timeZone = TimeZone.getDefault()
                return simpleDateFormat.parse(text)
            } catch (e: ParseException) {
                // ignore and try next pattern
            }
        }
        return null
    }
    

    请注意,对于 Android 11 及更高版本,您必须在 AndroidManifest.xml 文件中添加查询声明,以满足 Android 的软件包可见性要求:

    <manifest package="com.example.game">
        <queries>
            <package android:name="com.google.android.modulemetadata" />
        </queries>
        ...
    </manifest>

    信任代理可以使用这些方法来验证设备是否处于管理模式以及哪种管理模式处于活动状态。

    检查设备管理

    使用 getActiveAdmins() 检查设备是否受管理。如果此方法返回 null,则表示设备处于非受管状态。

    检查是否为完全受公司管理的设备

    使用 isDeviceOwnerApp() 检查设备是否处于全托管状态。

    检查公司自有设备上是否有工作资料

    使用 isOrganizationOwnedDeviceWithManagedProfile() 检查设备是否使用了适用于公司自有设备的工作资料管理模式

    检查个人所有设备上是否有工作资料

    使用 isProfileOwnerApp() 检查应用是否在工作资料中运行,并验证 isOrganizationOwnedDeviceWithManagedProfile() 是否返回 false