零信任信号

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

特征 说明 全代管式设备 公司自有设备上的工作资料 个人设备(自带设备)上的工作资料 不受管理的设备
Play Integrity API 信任代理可以检索以下信号:
  • 设备完整性
  • 应用完整性
  • Play 许可详细信息
  • 环境详情(包括新的 Play 保护机制判定)
  • 安全硬件提供 / 密钥认证 信任代理可以验证其 PKI 凭据是否已生成并存储在安全硬件中
    设备属性认证 在密钥认证过程中,设备属性可以包含在认证记录中
    设备安全补丁级别 信任代理可以验证操作系统安全补丁级别
    设备是否有待处理的 OTA 信任代理可以检查是否有待处理的设备操作系统更新 不适用
    Mainline 安全补丁级别 信任代理可以读取已安装的 Mainline 模块序列的安全补丁级别
    注册专用 ID 信任代理可以访问特定于该企业的唯一设备 ID。在重新创建工作资料和设备恢复出厂设置后,此 ID 仍然有效 不适用
    管理状态(以及管理应用) 信任代理可据此确定设备是否处于受管理状态 不适用
    磁盘加密 信任代理可以检查设备是否已加密(如果需要 Android 8 支持)
    操作系统版本 信任代理可以检查设备操作系统版本,并确认其是否超过特定版本
    访问网络状态(网络状态和 Wi-Fi 状态) 信任代理可以获取有关活跃网络状态(移动网络和 Wi-Fi)的信息
    访问 Wi-Fi 状态(Android 11 及更低版本,Android 12 及更高版本支持回调按需方法) 信任代理可以获取有关活跃 Wi-Fi 网络的信息
    代理设置 信任代理可以获取有关当前默认 HTTP 代理设置的信息。
    屏幕锁定质量检查 信任代理可以确保设备在授予访问权限之前配置了一定质量的屏幕锁定
    已启用开发者选项 启用开发者选项后,信任代理可将设备识别为具有更广泛的攻击面
    是否已启用 DNS over TLS 信任代理可利用这一点确保启用专用 DNS 模式
    SafetyNet 安全浏览 信任代理可以确定特定网址是否已被 Google 归类为已知威胁。
    装载外部媒体 装载外部存储设备时可通知信任代理
    UsageStatsManager 信任代理可以研究各个应用的使用模式 1
    安全日志记录 信任代理可将此类数据用作其上下文引擎的一部分,以确保合规性并创建基于行为的指纹 2 2 不适用
    网络日志记录 信任代理可将此类数据用作其上下文引擎的一部分,以确保合规性并创建基于行为的指纹 2 2 不适用
    NetworkStatsManager 信任代理可以查询给定时间间隔内应用的网络使用情况 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