HealthAttestation 云解决方案提供商

Windows 预览体验成员的徽标。

重要提示

此云解决方案提供商包含一些正在开发中的设置,仅适用于 Windows Insider Preview 版本。 这些设置可能会发生更改,并且可能依赖于预览版中的其他功能或服务。

Device HealthAttestation 配置服务提供商 (DHA-CSP) 使企业 IT 管理员能够评估设备是否已启动到受信任和合规状态,并采取企业策略操作。

以下列表描述了设备运行状况设置 CSP 执行的功能:

  • 从托管设备收集设备启动日志、受信任的平台模块 (TPM) 审核跟踪以及 TPM 证书 (DHA-BootData)
  • 将 DHA-BootData 转发到设备运行状况证明服务 (DHA-Service)
  • 从 DHA-Service 接收加密 blob (DHA-EncBlob) ,并将其存储在设备上的本地缓存中
  • 从 DHA-Enabled MDM 接收证明请求 (DHA-Requests) ,并使用设备运行状况证明数据 (DHA-Data)

以下列表显示了 HealthAttestation 配置服务提供程序节点:

AttestErrorMessage

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows Insider Preview
./Vendor/MSFT/HealthAttestation/AttestErrorMessage

AttestErrorMessage 维护最后一个证明会话的错误消息(如果由证明服务返回)。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 “获取”

AttestStatus

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 11版本 21H2 [10.0.22000] 及更高版本
./Vendor/MSFT/HealthAttestation/AttestStatus

AttestStatus 维护最后一个证明会话的成功或失败状态代码。

在进行证明服务调用之前,始终会清除状态。

描述框架属性:

属性名 属性值
格式 int
访问类型 “获取”

示例

  • 模板化 SyncML 调用:

    <SyncML xmlns="SYNCML:SYNCML1.2">
        <SyncBody>
        <Get>
            <Item>
            <Target>
                <LocURI>
                ./Device/Vendor/MSFT/HealthAttestation/AttestStatus
                </LocURI>
            </Target>
            </Item>
        </Get>
        <Final/>
        </SyncBody>
    </SyncML>
    
  • 示例响应:

    If Successful: 0
    If Failed: A corresponding HRESULT error code. Example: 0x80072efd,  WININET_E_CANNOT_CONNECT
    

证书

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/Certificate

指示 DHA-CSP 将 DHA-Data 转发到 MDM 服务器。

值类型是 base64 字符串。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 “获取”

CorrelationID

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/CorrelationID

标识唯一的设备运行状况证明会话。 CorrelationId 用于将 DHA-Service 日志与 MDM 服务器事件和客户端事件日志相关联,以便进行调试和故障排除。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 “获取”

CurrentProtocolVersion

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1709 [10.0.16299] 及更高版本
./Vendor/MSFT/HealthAttestation/CurrentProtocolVersion

提供客户端用于与运行状况证明服务通信的当前协议版本。

描述框架属性:

属性名 属性值
格式 int
访问类型 “获取”

ForceRetrieve

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/ForceRetrieve

指示客户端启动对 DHA-Service 的新请求,并获取新的 DHA-EncBlob (DHA-Service) 发出的启动状态摘要。 仅当 MDM 服务器强制实施证书新鲜度策略时,才应使用此选项,该策略需要强制设备从 DHA-Service 获取新的加密 Blob。

描述框架属性:

属性名 属性值
格式 bool
访问类型 获取、替换
默认值 False

允许的值:

描述
false (默认) 假。
true 真。

GetAttestReport

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 11版本 21H2 [10.0.22000] 及更高版本
./Vendor/MSFT/HealthAttestation/GetAttestReport

检索证明会话报告(如果存在)。

报表存储在相应 MDM 注册存储中的注册表项中。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 “获取”

示例

  • 模板化 SyncML 调用:

    <SyncML xmlns="SYNCML:SYNCML1.2">
    <SyncBody>
        <Get>
        <Item>
            <Target>
            <LocURI>
                ./Device/Vendor/MSFT/HealthAttestation/GetAttestReport
            </LocURI>
            </Target>
        </Item>
        </Get>
        <Final/>
    </SyncBody>
    </SyncML>
    
  • 示例数据:

    If Success: JWT token: aaaaaaaaaaaaa.bbbbbbbbbbbbb.cccccccccc
    If failed: Previously cached report if available (the token may have already expired per the attestation policy).
               OR Sync ML 404 error if no cached report available.
    

GetServiceCorrelationIDs

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 11版本 21H2 [10.0.22000] 及更高版本
./Vendor/MSFT/HealthAttestation/GetServiceCorrelationIDs

检索服务关联 ID(如果存在)。

如果有多个相关 ID,则用字符串中的“;”分隔它们。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 “获取”

示例

  • 模板化 SyncML 调用:

    <SyncML xmlns="SYNCML:SYNCML1.2">
      <SyncBody>
        <Get>
        <Item>
          <Target>
          <LocURI>
            ./Device/Vendor/MSFT/HealthAttestation/GetServiceCorrelationIDs
          </LocURI>
          </Target>
        </Item>
        </Get>
        <Final/>
      </SyncBody>
    </SyncML>
    
  • 示例数据:

    If success: GUID returned by the attestation service: 1k9+vQOn00S8ZK33;CMc969r1JEuHwDpM
    If Trigger Attestation call failed and no previous data is present: The field remains empty.
    Otherwise, the last service correlation id will be returned.
    In a successful attestation there are two calls between client and MAA and for each call the GUID is separated by semicolon.
    

HASEndpoint

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/HASEndpoint

标识分配给执行证明的 DHA-Service 的完全限定域名 (FQDN) 。 如果未分配 FQDN,DHA-Cloud (Microsoft 拥有和运营的云服务) 将用作默认证明服务。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 获取、替换
默认值 has.spserv.microsoft.com。

MaxSupportedProtocolVersion

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1709 [10.0.16299] 及更高版本
./Vendor/MSFT/HealthAttestation/MaxSupportedProtocolVersion

返回此客户端可以支持的最大协议版本。

描述框架属性:

属性名 属性值
格式 int
访问类型 “获取”

强奸犯

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/Nonce

使 MDM 能够保护设备运行状况证明通信免受中间人类型 (MITM) 攻击,该随机值由 MDM 服务器生成的受加密保护。 nonce 采用十六进制格式,最小大小为 8 个字节,最大大小为 32 个字节。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 获取、替换
默认值 \0

PreferredMaxProtocolVersion

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1709 [10.0.16299] 及更高版本
./Vendor/MSFT/HealthAttestation/PreferredMaxProtocolVersion

提供客户端配置为与之通信的最大首选协议版本。 如果这高于客户端支持的协议版本,它将使用可用的最高协议版本。

描述框架属性:

属性名 属性值
格式 int
访问类型 获取、替换
默认值 3

状态

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/Status

提供设备运行状况请求的当前状态。 有关状态值的完整列表,请参阅 HealthAttestation CSP 状态和错误代码

描述框架属性:

属性名 属性值
格式 int
访问类型 “获取”

TpmReadyStatus

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1607 [10.0.14393] 及更高版本
./Vendor/MSFT/HealthAttestation/TpmReadyStatus

返回描述 TPM 状态的信息的位掩码。 它指示设备的 TPM 是否处于就绪和受信任的状态。

描述框架属性:

属性名 属性值
格式 int
访问类型 “获取”

TriggerAttestation

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 11版本 21H2 [10.0.22000] 及更高版本
./Vendor/MSFT/HealthAttestation/TriggerAttestation

通知设备异步触发证明会话。

如果证明过程成功启动,此节点将返回代码 202,指示已接收并正在处理请求。 否则,将返回错误。

描述框架属性:

属性名 属性值
格式 chr (字符串)
访问类型 Exec

示例

  • 模板化 SyncML 调用:

    <SyncML xmlns="SYNCML:SYNCML1.2">
        <SyncBody>
            <Exec>
                <CmdID>VERIFYHEALTHV2</CmdID>
                <Item>
                    <Target>
                        <LocURI>
                            ./Vendor/MSFT/HealthAttestation/TriggerAttestation
                        </LocURI>
                    </Target>
                    <Data>
                        {
                        rpID : "rpID", serviceEndpoint : "MAA endpoint",
                        nonce : "nonce", aadToken : "aadToken", "cv" : "CorrelationVector"
                        }
                    </Data>
                </Item>
            </Exec>
            <Final/>
        </SyncBody>
    </SyncML>
    
  • 数据字段:

    • rpID (信赖方标识符) :此字段包含可用于帮助确定调用方的标识符。
    • serviceEndpoint:此字段包含用于评估的 Microsoft Azure 证明 提供程序实例的完整 URL。
    • nonce:此字段包含只能在加密通信中使用一次的任意数字。 它通常是在身份验证协议中颁发的随机或伪随机数,以确保旧通信不能在重播攻击中重复使用。
    • aadToken:用于对 Microsoft Azure 证明 服务进行身份验证的Microsoft Entra令牌。
    • cv:此字段包含一个标识符 (相关矢量) ,该标识符将传入服务调用,并且可用于诊断目的。
  • 示例 <Data>

    {
      "rpid" : "https://www.contoso.com/attestation",
      "endpoint" : "https://contoso.eus.attest.azure.net/attest/tpm?api-version=2020-10-01",
      "nonce" : "5468697320697320612054657374204e6f6e6365",
      "aadToken" : "dummytokenstring",
      "cv" : "testonboarded"
    }
    

VerifyHealth

范围 版本 适用的操作系统
✅ 设备
❌ 用户
✅ 专业版
✅ 企业版
✅ 教育版
✅ Windows SE
✅ IoT 企业版/IoT 企业版 LTSC
✅Windows 10版本 1511 [10.0.10586] 及更高版本
./Vendor/MSFT/HealthAttestation/VerifyHealth

通知设备准备设备运行状况验证请求。

描述框架属性:

属性名 属性值
格式 null
访问类型 Exec

Windows 11设备运行状况证明

Windows 11引入了设备运行状况证明功能的更新。 此更新有助于添加对 Windows 启动安全性更深入见解的支持,支持设备安全性的零信任方法。 可以使用 HealthAttestation CSP 访问 Windows 上的设备运行状况证明。 此 CSP 可帮助评估设备是否启动到受信任且合规的状态,然后采取适当的措施。 Windows 11向 HealthAttestation 节点引入了更多子节点,供 MDM 提供程序连接到 Microsoft Azure 证明 服务,从而简化了证明方法。

证明报告提供设备的启动时属性的运行状况评估,以确保设备在开机后立即自动安全。 然后,可以使用运行状况证明结果来允许或拒绝对网络、应用或服务的访问,具体取决于设备的运行状况。

使用的术语:

  • TPM (受信任的平台模块) :TPM 是一种受硬件保护的专用逻辑,可执行一系列硬件保护的安全操作,包括提供受保护的存储、随机编号生成、加密和签名。
  • DHA (Device HealthAttestation) 功能:设备 HealthAttestation (DHA) 功能使企业 IT 管理员可以使用硬件 (TPM 通过防篡改和防篡改的信道) 受保护且经过证明的数据,远程监视受管理设备的安全状况。
  • MAA 会话 (基于 Microsoft Azure 证明 服务的设备 HealthAttestation 会话) :基于 Microsoft Azure 证明 服务的设备 HealthAttestation 会话 (MAA 会话) 描述了在一个设备运行状况证明会话中执行的端到端通信流。
  • MAA-CSP 节点 (基于 Microsoft Azure 证明 的配置服务提供程序) :添加到 Windows 11 以与 Microsoft Azure 证明 服务集成的配置服务提供程序节点。 以下操作列表由 MAA-CSP 执行:
    • 接收来自已启用 HealthAttestation 的 MDM 提供程序的证明触发器请求。
    • 设备从托管设备收集证明证据 (设备启动日志、TPM 审核跟踪和 TPM 证书) 。
    • 将证明证据转发到 MDM 提供程序配置的 Azure 证明 服务实例。
    • 接收来自 Azure 证明 服务实例的已签名报表,并将其存储在设备上的本地缓存中。
  • MAA 终结点:Microsoft Azure 证明服务是 Azure 资源,服务的每个实例都获取管理员配置的 URL。 生成的 URI 本质上是唯一的,出于设备运行状况证明的目的,称为 MAA 终结点。
  • JWT (JSON Web 令牌) :JSON Web Token (JWT) 是一种开放标准RFC7519方法,用于在各方之间以 JavaScript 对象表示法 (JSON) 对象安全地传输信息。 此信息可以验证和信任,因为它经过数字签名。 可以使用机密或公钥/私钥对对 JWT 进行签名。

使用 Microsoft Azure 证明 服务证明流

使用 Microsoft Azure 证明 服务证明流

证明流大致可以分三个main步骤:

  • 使用适当的证明策略设置Azure 证明服务的实例。 证明策略允许 MDM 提供程序证明启动中的特定事件以及安全功能。
  • MDM 提供程序触发对证明服务的调用,然后设备执行证明检查使报表准备好检索。
  • MDM 提供程序在验证令牌是否来自证明服务后,可以分析证明令牌以反映设备的证明状态。

有关详细信息,请参阅 证明协议

MAA CSP 集成步骤

  1. 设置 MAA 提供程序实例:可以按照快速入门:使用 Azure 门户设置Azure 证明中的步骤创建 MAA 实例。

  2. 使用适当的策略更新提供程序:应使用适当的策略更新 MAA 实例。 有关详细信息,请参阅如何创作Azure 证明策略

    示例证明策略:

    version=1.2;
    
    configurationrules{
    };
    
    authorizationrules {
        => permit();
    };
    
    issuancerules {
    
        // SecureBoot enabled
        c:[type == "events", issuer=="AttestationService"] => add(type = "efiConfigVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG' && ProcessedData.VariableGuid == '8BE4DF61-93CA-11D2-AA0D-00E098032B8C']"));
        c:[type == "efiConfigVariables", issuer=="AttestationPolicy"]=> issue(type = "secureBootEnabled", value = JsonToClaimValue(JmesPath(c.value, "[?ProcessedData.UnicodeName == 'SecureBoot'] | length(@) == `1` && @[0].ProcessedData.VariableData == 'AQ'")));
        ![type=="secureBootEnabled", issuer=="AttestationPolicy"] => issue(type="secureBootEnabled", value=false);
    
        // Retrieve bool properties
        c:[type=="events", issuer=="AttestationService"] => add(type="boolProperties", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `13` || PcrIndex == `19` || PcrIndex == `20`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="codeIntegrityEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_CODEINTEGRITY")));
        c:[type=="codeIntegrityEnabledSet", issuer=="AttestationPolicy"] => issue(type="codeIntegrityEnabled", value=ContainsOnlyValue(c.value, true));
        ![type=="codeIntegrityEnabled", issuer=="AttestationPolicy"] => issue(type="codeIntegrityEnabled", value=false);
    
        // Bitlocker Boot Status, The first non zero measurement or zero.
        c:[type=="events", issuer=="AttestationService"] => add(type="srtmDrtmEventPcr", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `19`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
        c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => issue(type="bitlockerEnabledValue", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_BITLOCKER_UNLOCK | @[? Value != `0`].Value | @[0]")));
        [type=="bitlockerEnabledValue"] => issue(type="bitlockerEnabled", value=true);
        ![type=="bitlockerEnabledValue"] => issue(type="bitlockerEnabled", value=false);
    
        // Elam Driver (windows defender) Loaded
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="elamDriverLoaded", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_LOADEDMODULE_AGGREGATION[] | [? EVENT_IMAGEVALIDATED == `true` && (equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\wdboot.sys') || equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\wd\\wdboot.sys'))] | @ != `null`")));
        [type=="elamDriverLoaded", issuer=="AttestationPolicy"] => issue(type="WindowsDefenderElamDriverLoaded", value=true);
        ![type=="elamDriverLoaded", issuer=="AttestationPolicy"] => issue(type="WindowsDefenderElamDriverLoaded", value=false);
    
        // Boot debugging
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="bootDebuggingEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_BOOTDEBUGGING")));
        c:[type=="bootDebuggingEnabledSet", issuer=="AttestationPolicy"] => issue(type="bootDebuggingDisabled", value=ContainsOnlyValue(c.value, false));
        ![type=="bootDebuggingDisabled", issuer=="AttestationPolicy"] => issue(type="bootDebuggingDisabled", value=false);
    
        // Kernel Debugging
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="osKernelDebuggingEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_OSKERNELDEBUG")));
        c:[type=="osKernelDebuggingEnabledSet", issuer=="AttestationPolicy"] => issue(type="osKernelDebuggingDisabled", value=ContainsOnlyValue(c.value, false));
        ![type=="osKernelDebuggingDisabled", issuer=="AttestationPolicy"] => issue(type="osKernelDebuggingDisabled", value=false);
    
        // DEP Policy
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => issue(type="depPolicy", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_DATAEXECUTIONPREVENTION.Value | @[-1]")));
        ![type=="depPolicy"] => issue(type="depPolicy", value=0);
    
        // Test Signing
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="testSigningEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_TESTSIGNING")));
        c:[type=="testSigningEnabledSet", issuer=="AttestationPolicy"] => issue(type="testSigningDisabled", value=ContainsOnlyValue(c.value, false));
        ![type=="testSigningDisabled", issuer=="AttestationPolicy"] => issue(type="testSigningDisabled", value=false);
    
        // Flight Signing
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="flightSigningEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_FLIGHTSIGNING")));
        c:[type=="flightSigningEnabledSet", issuer=="AttestationPolicy"] => issue(type="flightSigningNotEnabled", value=ContainsOnlyValue(c.value, false));
        ![type=="flightSigningNotEnabled", issuer=="AttestationPolicy"] => issue(type="flightSigningNotEnabled", value=false);
    
        // VSM enabled
        c:[type=="events", issuer=="AttestationService"] => add(type="srtmDrtmEventPcr", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `19`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
        c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => add(type="vbsEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_VSM_REQUIRED")));
        c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => add(type="vbsEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_MANDATORY_ENFORCEMENT")));
        c:[type=="vbsEnabledSet", issuer=="AttestationPolicy"] => issue(type="vbsEnabled", value=ContainsOnlyValue(c.value, true));
        ![type=="vbsEnabled", issuer=="AttestationPolicy"] => issue(type="vbsEnabled", value=false);
        c:[type=="vbsEnabled", issuer=="AttestationPolicy"] => issue(type="vbsEnabled", value=c.value);
    
        // HVCI
        c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => add(type="hvciEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_HVCI_POLICY | @[?String == 'HypervisorEnforcedCodeIntegrityEnable'].Value")));
        c:[type=="hvciEnabledSet", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=ContainsOnlyValue(c.value, 1));
        ![type=="hvciEnabled", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=false);
    
        // IOMMU
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="iommuEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_IOMMU_REQUIRED")));
        c:[type=="iommuEnabledSet", issuer=="AttestationPolicy"] => issue(type="iommuEnabled", value=ContainsOnlyValue(c.value, true));
        ![type=="iommuEnabled", issuer=="AttestationPolicy"] => issue(type="iommuEnabled", value=false);
    
        // Find the Boot Manager SVN, this is measured as part of a sequence and find the various measurements
        // Find the first EV_SEPARATOR in PCR 12, 13, Or 14
        c:[type=="events", issuer=="AttestationService"] => add(type="evSeparatorSeq", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_SEPARATOR' && (PcrIndex == `12` || PcrIndex == `13` || PcrIndex == `14`)] | @[0].EventSeq"));
        c:[type=="evSeparatorSeq", value != "null", issuer=="AttestationPolicy"] => add(type="beforeEvSepClause", value=AppendString(AppendString("Events[? EventSeq < `", c.value), "`"));
        [type=="evSeparatorSeq", value=="null", issuer=="AttestationPolicy"] => add(type="beforeEvSepClause", value="Events[? `true` ");
    
        // Find the first EVENT_APPLICATION_SVN.
        c:[type=="beforeEvSepClause", issuer=="AttestationPolicy"] => add(type="bootMgrSvnSeqQuery", value=AppendString(c.value, " && EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `12` && ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_APPLICATION_SVN] | @[0].EventSeq"));
        c1:[type=="bootMgrSvnSeqQuery", issuer=="AttestationPolicy"] && c2:[type=="events", issuer=="AttestationService"] => add(type="bootMgrSvnSeq", value=JmesPath(c2.value, c1.value));
        c:[type=="bootMgrSvnSeq", value!="null", issuer=="AttestationPolicy"] => add(type="bootMgrSvnQuery", value=AppendString(AppendString("Events[? EventSeq == `", c.value), "`].ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_APPLICATION_SVN | @[0]"));
    
        // The first EVENT_APPLICATION_SVN. That value is the Boot Manager SVN
        c1:[type=="bootMgrSvnQuery", issuer=="AttestationPolicy"] && c2:[type=="events", issuer=="AttestationService"] => issue(type="bootMgrSvn", value=JsonToClaimValue(JmesPath(c2.value, c1.value)));
    
        // OS Rev List Info
        c:[type=="events", issuer=="AttestationService"] => issue(type="osRevListInfo", value=JsonToClaimValue(JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `13`].ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_OS_REVOCATION_LIST.RawData | @[0]")));
    
        // Safe mode
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="safeModeEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_SAFEMODE")));
        c:[type=="safeModeEnabledSet", issuer=="AttestationPolicy"] => issue(type="notSafeMode", value=ContainsOnlyValue(c.value, false));
        ![type=="notSafeMode", issuer=="AttestationPolicy"] => issue(type="notSafeMode", value=true);
    
        // Win PE
        c:[type=="boolProperties", issuer=="AttestationPolicy"] => add(type="winPEEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_WINPE")));
        c:[type=="winPEEnabledSet", issuer=="AttestationPolicy"] => issue(type="notWinPE", value=ContainsOnlyValue(c.value, false));
        ![type=="notWinPE", issuer=="AttestationPolicy"] => issue(type="notWinPE", value=true);
    
        // CI Policy
        c:[type=="events", issuer=="AttestationService"] => issue(type="codeIntegrityPolicy", value=JsonToClaimValue(JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `13`].ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_SI_POLICY[].RawData")));
    
        // Secure Boot Custom Policy
        c:[type=="events", issuer=="AttestationService"] => issue(type="secureBootCustomPolicy", value=JsonToClaimValue(JmesPath(c.value, "Events[? EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG' && PcrIndex == `7` && ProcessedData.UnicodeName == 'CurrentPolicy' && ProcessedData.VariableGuid == '77FA9ABD-0359-4D32-BD60-28F4E78F784B'].ProcessedData.VariableData | @[0]")));
    
        // Find the first EV_SEPARATOR in PCR 12, 13, Or 14
        c:[type=="events", issuer=="AttestationService"] => add(type="evSeparatorSeq", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_SEPARATOR' && (PcrIndex == `12` || PcrIndex == `13` || PcrIndex == `14`)] | @[0].EventSeq"));
        c:[type=="evSeparatorSeq", value != "null", issuer=="AttestationPolicy"] => add(type="beforeEvSepClause", value=AppendString(AppendString("Events[? EventSeq < `", c.value), "`"));
        [type=="evSeparatorSeq", value=="null", issuer=="AttestationPolicy"] => add(type="beforeEvSepClause", value="Events[? `true` "); // No restriction of EV_SEPARATOR in case it's not present
    
        //Finding the Boot App SVN
        // Find the first EVENT_TRANSFER_CONTROL with value 1 or 2 in PCR 12 which is before the EV_SEPARATOR
        c1:[type=="beforeEvSepClause", issuer=="AttestationPolicy"] && c2:[type=="bootMgrSvnSeq", value != "null", issuer=="AttestationPolicy"] => add(type="beforeEvSepAfterBootMgrSvnClause", value=AppendString(AppendString(AppendString(c1.value, "&& EventSeq >= `"), c2.value), "`"));
        c:[type=="beforeEvSepAfterBootMgrSvnClause", issuer=="AttestationPolicy"] => add(type="tranferControlQuery", value=AppendString(c.value, " && EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `12`&& (ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_TRANSFER_CONTROL.Value == `1` || ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_TRANSFER_CONTROL.Value == `2`)] | @[0].EventSeq"));
        c1:[type=="tranferControlQuery", issuer=="AttestationPolicy"] && c2:[type=="events", issuer=="AttestationService"] => add(type="tranferControlSeq", value=JmesPath(c2.value, c1.value));
    
        // Find the first non-null EVENT_MODULE_SVN in PCR 13 after the transfer control.
        c:[type=="tranferControlSeq", value!="null", issuer=="AttestationPolicy"] => add(type="afterTransferCtrlClause", value=AppendString(AppendString(" && EventSeq > `", c.value), "`"));
        c1:[type=="beforeEvSepClause", issuer=="AttestationPolicy"] && c2:[type=="afterTransferCtrlClause", issuer=="AttestationPolicy"] => add(type="moduleQuery", value=AppendString(AppendString(c1.value, c2.value), " && EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `13` && ((ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_LOADEDMODULE_AGGREGATION[].EVENT_MODULE_SVN | @[0]) || (ProcessedData.EVENT_LOADEDMODULE_AGGREGATION[].EVENT_MODULE_SVN | @[0]))].EventSeq | @[0]"));
        c1:[type=="moduleQuery", issuer=="AttestationPolicy"] && c2:[type=="events", issuer=="AttestationService"] => add(type="moduleSeq", value=JmesPath(c2.value, c1.value));
    
        // Find the first EVENT_APPLICATION_SVN after EV_EVENT_TAG in PCR 12.
        c:[type=="moduleSeq", value!="null", issuer=="AttestationPolicy"] => add(type="applicationSvnAfterModuleClause", value=AppendString(AppendString(" && EventSeq > `", c.value), "`"));
        c1:[type=="beforeEvSepClause", issuer=="AttestationPolicy"] && c2:[type=="applicationSvnAfterModuleClause", issuer=="AttestationPolicy"] => add(type="bootAppSvnQuery", value=AppendString(AppendString(c1.value, c2.value), " && EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `12`].ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_APPLICATION_SVN | @[0]"));
        c1:[type=="bootAppSvnQuery", issuer=="AttestationPolicy"] && c2:[type=="events", issuer=="AttestationService"] => issue(type="bootAppSvn", value=JsonToClaimValue(JmesPath(c2.value, c1.value)));
    
        // Finding the Boot Rev List Info
        c:[type=="events", issuer=="AttestationService"] => issue(type="bootRevListInfo", value=JsonToClaimValue(JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && PcrIndex == `13`].ProcessedData.EVENT_TRUSTBOUNDARY.EVENT_BOOT_REVOCATION_LIST.RawData | @[0]")));
    
    };
    
  3. 使用 和 rpidAzure Active Directory tokenattestURI调用 TriggerAttestation:使用步骤 1 中生成的证明 URL,并追加要命中的适当 API 版本。 有关 API 版本的详细信息,请参阅 证明 - 证明 Tpm - REST API

  4. 调用 GetAttestReport 并解码和分析报表,以确保证明的报表包含所需属性:GetAttestReport 将已签名的证明令牌作为 JWT 返回。 可以根据证明策略对 JWT 进行解码以分析信息。

        {
          "typ": "JWT",
          "alg": "RS256",
          "x5c": [
            "MIIE.....=",
            "MIIG.....=",
            "MIIF.....="
          ],
          "kid": "8FUer20z6wzf1rod044wOAFdjsg"
        }.{
          "nbf": 1633664812,
          "exp": 1634010712,
          "iat": 1633665112,
          "iss": "https://contosopolicy.eus.attest.azure.net",
          "jti": "2b63663acbcafefa004d20969991c0b1f063c9be",
          "ver": "1.0",
          "x-ms-ver": "1.0",
          "rp_data": "AQIDBA",
          "nonce": "AQIDBA",
          "cnf": {
            "jwk": {
              "kty": "RSA",
              "n": "yZGC3-1rFZBt6n6vRHjRjvrOYlH69TftIQWOXiEHz__viQ_Z3qxWVa4TfrUxiQyDQnxJ8-f8tBRmlunMdFDIQWhnew_rc3-UYMUPNcTQ0IkrLBDG6qDjFFeEAMbn8gqr0rRWu_Qt7Cb_Cq1upoEBkv0RXk8yR6JXmFIvLuSdewGs-xCWlHhd5w3n1rVk0hjtRk9ZErlbPXt74E5l-ZZQUIyeYEZ1FmbivOIL-2f6NnKJ-cR4cdhEU8i9CH1YV0r578ry89nGvBJ5u4_3Ib9Ragdmxm259npH53hpnwf0I6V-_ZhGPyF6LBVUG_7x4CyxuHCU20uI0vXKXJNlbj1wsQ",
              "e": "AQAB"
            }
          },
          "x-ms-policy-hash": "GiGQCTOylCohHt4rd3pEppD9arh5mXC3ifF1m1hONh0",
          "WindowsDefenderElamDriverLoaded": true,
          "bitlockerEnabled": true,
          "bitlockerEnabledValue": 4,
          "bootAppSvn": 1,
          "bootDebuggingDisabled": true,
          "bootMgrSvn": 1,
          "bootRevListInfo": "gHWqR2F-1wEgAAAACwBxrZXHbaiuTuO0PSaJ7WQMF8yz37Z2ATgSNTTlRkwcTw",
          "codeIntegrityEnabled": true,
          "codeIntegrityPolicy": [
            "AAABAAAAAQBWAAsAIAAAAHsAOABmAGIANAA4ADYANQBlAC0AZQA5ADAAYgAtADQANAA0AGYALQBiADUAYgA1AC0AZQAyAGEAYQA1ADEAZAA4ADkAMABmAGQAfQAuAEMASQBQAAAAVnW86ERqAg5n9QT1UKFr-bOP2AlNtBaaHXjZODnNLlk", "AAAAAAAACgBWAAsAIAAAAHsAYgBjADQAYgBmADYAZAA3AC0AYwBjADYAMAAtADQAMABmADAALQA4ADYANAA0AC0AMQBlADYANAA5ADEANgBmADgAMQA4ADMAfQAuAEMASQBQAAAAQ7vOXuAbBRIMglSSg7g_LHNeHoR4GrY-M-2W5MNvf0o", "AAAAAAAACgBWAAsAIAAAAHsAYgAzADEAOAA5ADkAOQBhAC0AYgAxADMAZQAtADQANAA3ADUALQBiAGMAZgBkAC0AMQBiADEANgBlADMAMABlADYAMAAzADAAfQAuAEMASQBQAAAALTmwU3eadNtg0GyAyKIAkYed127RJCSgmfFmO1jN_aI", "AAAAAAAACgBWAAsAIAAAAHsAZgBlADgAMgBkADUAOAA5AC0ANwA3AGQAMQAtADQAYwA3ADYALQA5AGEANABhAC0AZQA0ADUANQA0ADYAOAA4ADkANAAxAGIAfQAuAEMASQBQAAAA8HGUwA85gHN_ThItTYtu6sw657gVuOb4fOhYl-YJRoc", "AACRVwAACgAmAAsAIAAAAEQAcgBpAHYAZQByAFMAaQBQAG8AbABpAGMAeQAuAHAANwBiAAAAYcVuY0HdW4Iqr5B-6Sl85kwIXRG9bqr43pVhkirg4qM"
          ],
          "depPolicy": 0,
          "flightSigningNotEnabled": false,
          "hvciEnabled": true,
          "iommuEnabled": true,
          "notSafeMode": true,
          "notWinPE": true,
          "osKernelDebuggingDisabled": true,
          "osRevListInfo": "gHLuW2F-1wEgAAAACwDLyDTUQILjdz_RfNlShVgNYT9EghL7ceMReWg9TuwdKA",
          "secureBootEnabled": true,
          "testSigningDisabled": true,
          "vbsEnabled": true
        }.[Signature]
    

了解详细信息

可在此处找到有关 TPM 证明的详细信息:Microsoft Azure 证明

Windows 10设备运行状况Attestation

使用的术语:

  • TPM (受信任的平台模块) :TPM 是一种受硬件保护的专用逻辑,可执行一系列硬件保护的安全操作,包括提供受保护的存储、随机编号生成、加密和签名。

  • DHA (Device HealthAttestation) 功能:设备 HealthAttestation (DHA) 功能使企业 IT 管理员可以使用硬件 (TPM 通过防篡改和防篡改的信道) 受保护且经过证明的数据,远程监视受管理设备的安全状况。

  • 已启用 DHA 的设备 (已启用设备运行状况的设备) :已启用设备运行状况设置 (已启用 DHA 的) 设备是一种计算设备, (手机、台式机、笔记本电脑、平板电脑、服务器) 运行Windows 10并支持 TPM 版本 1.2 或 2.0。

  • DHA-Session (Device HealthAttestation 会话) :设备运行状况访问会话 (DHA-Session) 描述在一个设备运行状况证明会话中执行的端到端通信流。 以下事务列表在一个 DHA 会话中执行:

    DHA 会话运行状况设置会话关系图

    • DHA-CSP 和 DHA-Service 通信:
      • DHA-CSP 将设备启动数据 (DHA-BootData) 转发到 DHA-Service
      • 使用加密数据 blob (DHA-EncBlob) DHA-Service 答复
    • DHA-CSP 和 MDM-Server 通信:
      • MDM-Server 向 DHA-CSP 发送设备运行状况验证请求
      • DHA-CSP 使用名为 DHA-Data 的有效负载进行答复,该有效负载包括加密的 (DHA-EncBlob) 和已签名的 (DHA-SignedBlob) 数据 blob
    • MDM-Server 和 DHA-Service 通信:
      • MDM-Server 它从设备接收的数据发布到 DHA-Service
      • DHA-Service 评审接收的数据,并使用设备运行状况报告 (DHA-Report)
  • DHA 会话数据 (设备运行状况Attestation 会话数据) :在一个 DHA 事务中生成或使用以下数据列表:

    • DHA-BootData:设备启动数据 (验证设备启动运行状况所需的 TCG 日志、PCR 值、设备/TPM 证书、启动和 TPM 计数器) 。
    • DHA-EncBlob:一个加密的摘要报告,在查看设备从设备收到的 DHA-BootData 后,DHA-Service 问题。
    • DHA-SignedBlob:它是设备运行时当前状态的已签名快照,由 DHA-CSP 在设备运行状况证明时捕获。
    • DHA-Data:一个 XML 格式的数据 Blob,设备通过 MDM-Server 转发用于设备运行状况验证 DHA-Service。 DHA-Data 包含两个部分:
      • DHA-EncBlob:设备从 DHA-Service 接收的加密数据 blob
      • DHA-SignedBlob:DHA-CSP 生成的设备的当前安全状态的当前快照
    • DHA-Report:由 DHA-Service 颁发给 MDM-Server 的报告
    • Nonce:MDM-Server 生成的加密保护号码,可保护 DHA-Session 免受中间人类型攻击
  • 已启用 DHA 的 MDM (已启用设备运行状况Attestation 的设备管理解决方案) :已启用设备运行状况设置 (已启用 DHA 的设备管理解决方案) 设备管理解决方案是与 DHA 功能集成的设备管理工具。 DHA-Enabled 设备管理解决方案使企业 IT 经理能够基于硬件 (TPM 提高托管设备的安全保护标准,) 可以信任这些数据,即使设备受到高级安全威胁的攻击或运行恶意 (越狱) 操作系统也是如此。 以下操作列表由 DHA-Enabled-MDM 执行:

    • 在 DHA-Enabled 设备上启用 DHA 功能
    • 向已注册/托管的设备发出设备运行状况证明请求
    • (DHA-Data) 收集设备运行状况证明数据,并将其发送到设备运行状况证明服务 (DHA-Service) 进行验证
    • 从 DHA-Service 获取设备运行状况报告 (DHA-Report) ,这会触发合规性操作
  • DHA-CSP (Device HealthAttestation Configuration Service Provider) :Device HealthAttestation Configuration Service Provider (DHA-CSP) 使用设备的 TPM 和固件来测量设备的 BIOS 和 Windows 启动的关键安全属性,因此,即使在感染了内核级别恶意软件或 rootkit 的系统上,也无法欺骗这些属性。 以下操作列表由 DHA-CSP 执行:

    • (DHA-BootData) 从托管设备收集设备启动数据
    • 将 DHA-BootData 转发到设备运行状况证明服务 (DHA-Service)
    • 从 DHA-Service 接收加密 blob (DHA-EncBlob) ,并将其存储在设备上的本地缓存中
    • 从 DHA-Enabled MDM 接收证明请求 (DHA-Requests) ,并使用设备运行状况证明数据 (DHA-Data)
  • DHA-Service (Device HealthAttestation Service) :Device HealthAttestation Service (DHA-Service) 验证它从 DHA-CSP 接收的数据,并发出高度受信任的硬件 (TPM) 受保护的报告 (DHA-Report) ,通过防篡改和防篡改的信道 DHA-Enabled 设备管理解决方案。 DHA-Service 有两种类型:“DHA-Cloud”和“DHA-Server2016”。 DHA-Service 支持各种实现方案,包括云、本地、气隙和混合方案。 以下操作列表由 DHA-Service 执行:

    • 从 DHA-Enabled 设备接收设备启动数据 (DHA-BootData)
    • 将 DHA-BootData 转发到设备运行状况证明服务 (DHA-Service)
    • 从 DHA-Service 接收加密 blob (DHA-EncBlob) ,并将其存储在设备上的本地缓存中
    • 接收来自 DHA-Enabled-MDM (DHA-Requests) 的证明请求,并使用设备运行状况报告 (DHA-Report)

不同 DHS 服务的运行状况证明服务关系图

DHA-Service 类型 描述 运营成本
设备运行状况证明 - 云 (DHA-Cloud) DHA-Cloud 是 Microsoft 拥有和运营的 DHA-Service,即:
  • 在 Windows 中免费提供
  • 在高可用性和异地均衡的云基础结构上运行
  • 受大多数 DHA-Enabled 设备管理解决方案作为默认设备证明服务提供商的支持
  • 可通过以下方式访问所有企业托管设备:
    • FQDN = has.spserv.microsoft.com 端口
    • 端口 = 443
    • 协议 = TCP
  • 无成本
    设备运行状况证明 - 本地 (DHA-OnPrem) DHA-OnPrem 是指在本地运行的 DHA-Service:
  • 提供给Windows Server 2016客户 (启用/运行 DHA 服务) 不增加许可成本
  • 托管在企业拥有和托管的服务器设备/硬件上
  • 受第一方和第三方 DHA-Enabled 设备管理解决方案提供商的支持,这些提供商支持本地和混合 (云 + OnPrem) 硬件证明方案
  • 可通过以下设置访问所有企业托管设备:
    • FQDN = (企业分配)
    • 端口 = (企业分配)
    • 协议 = TCP
  • 在本地运行一个或多个 Server 2016 实例的操作成本。
    设备运行状况证明 - Enterprise-Managed Cloud (DHA-EMC) DHA-EMC 是指企业托管的 DHA-Service,它作为虚拟主机/服务在Windows Server 2016兼容的企业托管云服务(如 Microsoft Azure)上运行。
  • 提供给Windows Server 2016客户,无需额外的许可费用 (启用/运行 DHA-Service)
  • 受第一方和第三方 DHA-Enabled 设备管理解决方案提供商的支持,这些提供商支持本地和混合 (云 + OnPrem) 硬件证明方案
  • 可通过以下设置访问所有企业托管设备:
    • FQDN = (企业分配)
    • 端口 = (企业分配)
    • 协议 = TCP
  • 在兼容的云服务(如 Microsoft Azure)上运行 Server 2016 的运营成本。

    DHA-CSP 集成步骤

    将 Microsoft 设备运行状况证明功能与 Windows Mobile 设备管理解决方案集成 (MDM) 需要以下验证和开发任务列表:

    1. 验证 HTTPS 访问
    2. 分配企业受信任的 DHA-Service
    3. 指示客户端准备 DHA 数据进行验证
    4. 根据客户端响应执行操作
    5. 指示客户端转发 DHA 数据进行验证
    6. 将 DHA 数据发布到 DHA-service
    7. 接收来自 DHA-service 的响应
    8. 分析 DHA-Report 数据。 根据评估结果采取适当的策略操作

    本主题的以下部分详细介绍了每个步骤。

    步骤 1:验证 HTTPS 访问

    验证 MDM 服务器和设备 (MDM 客户端) 是否可以通过端口 443 (HTTPS) 使用 TCP 协议访问 has.spserv.microsoft.com。

    可以使用 OpenSSL 验证对 DHA-Service 的访问。 下面是示例 OpenSSL 命令以及 DHA-Service 生成的响应:

    PS C:\openssl> ./openssl.exe s_client -connect has.spserv.microsoft.com:443
    CONNECTED(000001A8)
    ---
    Certificate chain
     0 s:/CN=*.spserv.microsoft.com
       i:/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=Microsoft IT/CN=Microsoft IT SSL SHA2
     1 s:/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=Microsoft IT/CN=Microsoft IT SSL SHA2
       i:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIGOTCCBCGgAwIBAgITWgAA1KJb40tpukQoewABAADUojANBgkqhkiG9w0BAQsFA4ICAQCJaKewFQuqQwR5fkAr9kZOmtq5fk03p82eHWLaftXlc4RDvVFp4a2ciSjZL8f3f+XWPVdUj9DAi3bCSddlrcNOPRXNepFC1OEmKtE9jM0r7M8qnqFkIfbNrVNUtPxHoraQeMIgbk0SHEOlShY2GXETVBqZdDZ5Rmk4rA+3ggoeV8hNzm2dfNp0iGSrZzawbLzWU1D2Tped1k5IV63yb+cU/TmM ……………………………………………………………………………………………………………………………………
    ………………………………………………………………………………………………………………………………………………………………………………………………………………………………
    ……………2RXXwogn1UM8TZduCEjz+b05mAkvytugzzaI4wXkCP4OgNyy8gul2z5Gj/51pCTN
    -----END CERTIFICATE-----
    subject=/CN=*.spserv.microsoft.com
    issuer=/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/OU=Microsoft IT/CN=Microsoft IT SSL SHA2
    ---
    No client certificate CA names sent
    Peer signing digest: SHA1
    Server Temp Key: ECDH, P-384, 384 bits
    ---
    SSL handshake has read 3681 bytes and written 561 bytes
    New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol: TLSv1.2
        Cipher: ECDHE-RSA-AES256-SHA384
        Session-ID: B22300009621370F84A4A3A7D9FC40D584E047C090604E5226083A02ED239C93
        Session-ID-ctx:
        Master-Key: 9E3F6BE5B3D3B55C070470CA2B62EF59CC1D5ED9187EF5B3D1BBF4C101EE90BEB04F34FFD748A13C92A387104B8D1DE7
        Key-Arg: None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1432078420
        Timeout: 300 (sec)
        Verify return code: 20 (unable to get local issuer certificate)
    

    步骤 2:分配企业受信任的 DHA-Service

    DHA 服务有三种类型:

    • 设备运行状况证明 - Microsoft) 拥有和运营的云 (
    • 设备运行状况证明 - 本地 (企业拥有和运营,在本地Windows Server 2016上运行)
    • 设备运行状况证明 - Enterprise-Managed 云 (企业拥有和运营,在兼容的企业托管云Windows Server 2016上运行)

    DHA-Cloud 是默认设置。 如果企业计划将 Microsoft DHA-Cloud 用作受信任的 DHA-Service 提供商,则无需采取进一步操作。

    对于 DHA-OnPrem & DHA-EMC 方案,请将 SyncML 命令发送到 HASEndpoint 节点,以指示托管设备与企业受信任的 DHA-Service 通信。

    以下示例演示了一个示例调用,该调用指示托管设备与企业管理的 DHA-Service 通信。

    <Replace>
        <CmdID>1</CmdID>
        <Item>
          <Target>
              <LocURI>./Vendor/MSFT/HealthAttestation/HASEndpoint</LocURI>
          </Target>
          <Data> www.ContosoDHA-Service</Data>
        </Item>
    </Replace>
    

    步骤 3:指示客户端准备运行状况数据以供验证

    发送 SyncML 调用以开始收集 DHA-Data。

    以下示例演示了一个示例调用,该调用触发从托管设备收集和验证运行状况证明数据。

    <Exec>
        <CmdID>1</CmdID>
        <Item>
          <Target>
              <LocURI>./Vendor/MSFT/HealthAttestation/VerifyHealth</LocURI>
          </Target>
        </Item>
    </Exec>
    
    <Get>
        <CmdID>2</CmdID>
        <Item>
          <Target>
              <LocURI>./Vendor/MSFT/HealthAttestation/Status</LocURI>
          </Target>
        </Item>
    </Get>
    

    步骤 4:根据客户端的响应执行操作

    客户端收到运行状况证明请求后,会发送响应。 以下列表介绍了响应以及要采取的推荐操作。

    • 如果响应HEALTHATTESTATION_CERT_RETRIEVAL_COMPLETE (3) 则继续下一部分。
    • 如果响应HEALTHATTESTATION_CERT_RETRIEVAL_REQUESTED (1) 或HEALTHATTESTATION_CERT_RETRIEVAL_UNINITIALIZED (0) 等待警报,则继续下一部分。

    下面是DHA_CSP发出的示例警报:

    <Alert>
        <CmdID>1</CmdID>
        <Data>1226</Data>
        <Item>
            <Source>
                <LocURI>./Vendor/MSFT/HealthAttestation/VerifyHealth</LocURI>
            </Source>
            <Meta>
                <Type xmlns="syncml:metinf">com.microsoft.mdm:HealthAttestation.Result</Type>
                <Format xmlns="syncml:metinf">int</Format>
            </Meta>
            <Data>3</Data>
        </Item>
    </Alert>
    

    步骤 5:指示客户端转发运行状况证明数据进行验证

    创建对 NonceCertificateCorrelationId 节点的调用,并从设备中选取包含运行状况证书和相关数据的加密有效负载。

    下面是一个示例:

    <Replace>
        <CmdID>1</CmdID>
        <Item>
            <Target>
                <LocURI>./Vendor/MSFT/HealthAttestation/Nonce</LocURI>
            </Target>
            <Data>AAAAAAAAAFFFFFFF</Data>
        </Item>
    </Replace>
    
    <Get>
        <CmdID>2</CmdID>
        <Item>
            <Target>
                <LocURI>./Vendor/MSFT/HealthAttestation/Certificate</LocURI>
            </Target>
        </Item>
    </Get>
    
    <Get>
        <CmdID>3</CmdID>
        <Item>
            <Target>
                <LocURI>./Vendor/MSFT/HealthAttestation/CorrelationId </LocURI>
            </Target>
        </Item>
    </Get>
    

    步骤 6:将设备运行状况证明数据转发到 DHA-service

    为了响应在上一步中发送的请求,MDM 客户端转发来自 ./Vendor/MSFT/HealthAttestation/Certificate 节点) 的 XML 格式化 blob (响应,并将名为 CorrelationId 的调用标识符 (转发到 ./Vendor/MSFT/HealthAttestation/CorrelationId 节点) 的响应。

    当 MDM-Server 收到上述数据时,它必须:

    • 记录它从设备 (收到的 CorrelationId,以便将来进行故障排除/参考) ,与调用相关。

    • 解码它从设备接收的 XML 格式化数据 Blob

    • 追加 MDM 服务生成的 nonce, (将步骤 5) 中转发到设备的 nonce 添加到设备以以下格式转发的 XML 结构:

      <?xml version='1.0' encoding='utf-8' ?>
      <HealthCertificateValidationRequest ProtocolVersion='1' xmlns='http://schemas.microsoft.com/windows/security/healthcertificate/validation/request/v1'>
          <Nonce>[INT]</Nonce>
          <Claims> [base64 blob, eg ‘ABc123+/…==’] </Claims>
          <HealthCertificateBlob> [base64 blob, eg ‘ABc123+/...==’]
          </HealthCertificateBlob>
      </HealthCertificateValidationRequest>
      
    • 转发 (HTTP Post) XML 数据结构 (包括上一步骤中追加的 nonce) 到在其上运行的分配 DHA-Service:

      • DHA-Cloud (Microsoft 拥有和运营的 DHA-Service) 方案: https://has.spserv.microsoft.com/DeviceHealthAttestation/ValidateHealthCertificate/v3
      • DHA-OnPrem 或 DHA-EMC: https://FullyQualifiedDomainName-FDQN/DeviceHealthAttestation/ValidateHealthCertificate/v3

    步骤 7:接收来自 DHA 服务的响应

    当 Microsoft 设备运行状况证明服务收到验证请求时,它会执行以下步骤:

    • 解密它收到的加密数据。
    • 验证它收到的数据。
    • 创建报表,并通过 XML 格式的 SSL 将评估结果共享到 MDM 服务器。

    步骤 8:根据评估结果采取适当的策略操作

    MDM 服务器收到已验证的数据后,该信息可用于通过评估数据来做出策略决策。 一些可能的操作是:

    • 允许设备访问。
    • 允许设备访问资源,但标记设备以供进一步调查。
    • 阻止设备访问资源。

    DHA-Report V3 架构

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns="http://schemas.microsoft.com/windows/security/healthcertificate/validation/response/v3"
               targetNamespace="http://schemas.microsoft.com/windows/security/healthcertificate/validation/response/v3"
               elementFormDefault="qualified">
    
        <xs:element name="HealthCertificateValidationResponse" type="HealthCertificateValidationResponse_T"/>
        <xs:complexType name="ResponseCommon_T">
            <xs:attribute name="ErrorCode" type="xs:int" use="required"/>
            <xs:attribute name="ErrorMessage" type="xs:string" use="required"/>
            <xs:attribute name="ProtocolVersion" use="required">
              <xs:simpleType>
                <xs:restriction base="xs:int">
                  <xs:minInclusive value="3"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
        <xs:complexType name="HealthCertificatePublicProperties_T">
            <xs:annotation>
                <xs:documentation>Health certificate non machine identifiable properties </xs:documentation>
            </xs:annotation>
            <xs:sequence>
                <xs:element name="Issued"                       type="xs:dateTime"/>
                <xs:element name="AIKPresent"                   type="Boolean_T" />
                <xs:element name="ResetCount"                   type="xs:unsignedInt"/>
                <xs:element name="RestartCount"                 type="xs:unsignedInt"/>
                <xs:element name="DEPPolicy"                    type="xs:unsignedInt"/>
                <xs:element name="BitlockerStatus"              type="xs:unsignedInt"/>
                <xs:element name="BootManagerRevListVersion"    type="xs:unsignedInt"/>
                <xs:element name="CodeIntegrityRevListVersion"  type="xs:unsignedInt"/>
                <xs:element name="SecureBootEnabled"            type="Boolean_T"/>
                <xs:element name="BootDebuggingEnabled"         type="Boolean_T"/>
                <xs:element name="OSKernelDebuggingEnabled"     type="Boolean_T"/>
                <xs:element name="CodeIntegrityEnabled"         type="Boolean_T"/>
                <xs:element name="TestSigningEnabled"           type="Boolean_T"/>
                <xs:element name="SafeMode"                     type="Boolean_T"/>
                <xs:element name="WinPE"                        type="Boolean_T"/>
                <xs:element name="ELAMDriverLoaded"             type="Boolean_T"/>
                <xs:element name="VSMEnabled"                   type="Boolean_T"/>
                <xs:element name="PCRHashAlgorithmID"           type="xs:unsignedInt"/>
                <xs:element name="BootAppSVN"                   type="xs:unsignedInt"/>
                <xs:element name="BootManagerSVN"               type="xs:unsignedInt"/>
                <xs:element name="TpmVersion"                   type="xs:unsignedInt"/>
                <xs:element name="PCR0"                         type="xs:hexBinary"/>
                <xs:element name="CIPolicy"                     type="xs:hexBinary" minOccurs ="0" maxOccurs ="1"/>
                <xs:element name="SBCPHash"                     type="xs:hexBinary" minOccurs ="0" maxOccurs ="1"/>
                <xs:element name="BootRevListInfo"              type="xs:hexBinary" minOccurs ="0" maxOccurs ="1"/>
                <xs:element name="OSRevListInfo"                type="xs:hexBinary" minOccurs ="0" maxOccurs ="1"/>
    
              <!--
    <xs:element name="PCRCount"                     type="xs:unsignedInt"/>
    <xs:element name="PCRSize"                      type="xs:unsignedShort"/>
    <xs:element name="PCRHashAlgorithmID"           type="xs:unsignedShort"/>
    
    <xs:element name="PCR"                          type="xs:hexBinary"/>
                -->
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="HealthStatusMismatchFlags_T">
            <xs:annotation>
                <xs:documentation>If there's a status mismatch, these flags will be set</xs:documentation>
            </xs:annotation>
            <xs:sequence>
                <!-- Hibernate/Resume count -->
                <xs:element name="ResumeCount"                   type="Boolean_T"/>
                <!-- Reboot count -->
                <xs:element name="RebootCount"                   type="Boolean_T"/>
                <xs:element name="PCR"                           type="Boolean_T"/>
                <xs:element name="BootAppSVN"                   type="Boolean_T"/>
                <xs:element name="BootManagerSVNChain"           type="Boolean_T"/>
                <xs:element name="BootAppSVNChain"              type="Boolean_T"/>
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="HealthCertificateValidationResponse_T" >
            <xs:annotation>
                <xs:documentation>Health certificate validation response </xs:documentation>
            </xs:annotation>
            <xs:complexContent>
                <xs:extension base="ResponseCommon_T">
    <xs:sequence>
        <!--Optional element, present only when the certificate can be verified and decrypted-->
        <xs:element name="HealthCertificateProperties"  type="HealthCertificatePublicProperties_T"  minOccurs="0"/>
        <!--Optional element, present only when the reason for a validation failure is a mismatch between the
                        current health state and the certificate health state-->
        <xs:element name="HealthStatusMismatchFlags"       type="HealthStatusMismatchFlags_T"             minOccurs="0"/>
    </xs:sequence>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
        <xs:simpleType name="Boolean_T">
            <xs:restriction base="xs:boolean">
                <xs:pattern value="true|false"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:schema>
    

    以下数据点列表由 DHA-Report 版本 3 中的 DHA-Service 验证。

    • 已颁发:评估 DHA 报告或颁发给 MDM 的日期和时间。

    • AIKPresent:当设备上存在证明标识密钥 (AIK) 时,指示设备具有 EK) 证书 (认可密钥。 它比没有 EK 证书的设备更受信任。

      如果 AIKPresent = True (1) ,则允许访问。

      如果 AIKPresent = False (0) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 允许基于评估时存在的其他数据点的条件访问。 例如,运行状况证书上的其他属性,或设备过去的活动和信任历史记录。
      • 执行上述操作之一,并将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • ResetCount (仅适用于支持 TPM 2.0) 的设备:此属性报告电脑设备进入休眠或恢复的次数。

    • RestartCount (仅适用于支持 TPM 2.0) 的设备:此属性报告电脑设备重新启动的次数。

    • DEPPolicy:如果设备上启用了 DEP 策略,则可以更信任设备。

      数据执行防护 (DEP) 策略定义了一组硬件和软件技术,这些技术对内存执行额外检查,以帮助防止恶意代码在系统上运行。 安全启动允许在 x86/amd64 上列出有限的列表,在 ARM NTOS 上将其锁定为“打开”。

      可以在 WMI 或 PowerShell 脚本中使用以下命令来禁用或启用 DEPPolicy:

      • 若要禁用 DEP,请键入 bcdedit.exe /set {current} nx AlwaysOff
      • 若要启用 DEP,请键入 bcdedit.exe /set {current} nx AlwaysOn

      如果 DEPPolicy = 1 (on) ,则允许访问。

      如果 DEPPolicy = 0 (off) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 允许基于评估时存在的其他数据点的条件访问。 例如,运行状况证书上的其他属性,或设备过去的活动和信任历史记录。
      • 执行上述操作之一,并将设备置于watch列表中,以更密切地监视设备的潜在风险。

      查询时,DEP 策略评估是非二进制状态。 然后,它映射到开/关状态。

      DEP 策略级别 描述 证明报告级别 属性值
      OptIn (默认配置) 只有 Windows 系统组件和服务应用了 DEP。 0 2
      OptOut 为所有进程启用 DEP。 管理员可以手动创建未应用 DEP 的特定应用程序的列表。 1 3
      AlwaysOn 为所有进程启用 DEP。 3 1
      AlwaysOff 未对任何进程启用 DEP。 2 0
    • BitLockerStatus (报告在初始启动期间是否启用了 BitLocker。) :

      当 BitLocker 在启动时被报告为“开”时,当系统关闭或进入休眠状态时,设备能够保护存储在驱动器上的数据免受未经授权的访问。

      Windows BitLocker 驱动器加密,对存储在 Windows 操作系统卷中的所有数据进行加密。 BitLocker 使用 TPM 来帮助保护 Windows 操作系统和用户数据,并帮助确保计算机不会被篡改,即使计算机处于无人参与、丢失或被盗状态。

      如果计算机配备了兼容的 TPM,BitLocker 将使用 TPM 来锁定保护数据的加密密钥。 因此,在 TPM 验证计算机状态之前,无法访问密钥。

      如果 BitLockerStatus = 1 (on) ,则允许访问。

      如果 BitLockerStatus = 0 (off) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 允许基于评估时存在的其他数据点的条件访问。 例如,运行状况证书上的其他属性,或设备过去的活动和信任历史记录。
      • 执行上述操作之一,并将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • BootManagerRevListVersion:此属性指示在设备上运行的启动管理器版本,以便跟踪和管理启动序列/环境的安全性。

      如果 BootManagerRevListVersion = [CurrentVersion],则允许访问。

      如果 BootManagerRevListVersion != [CurrentVersion],请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 和 MBI 资产。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题。
    • CodeIntegrityRevListVersion:此属性指示在启动序列期间执行完整性检查的代码版本。 使用此属性可帮助你检测设备是否正在运行执行完整性检查的最新版本代码,或者它是否暴露在安全风险 (吊销) ,并强制实施适当的策略操作。

      如果 CodeIntegrityRevListVersion = [CurrentVersion],则允许访问。

      如果 CodeIntegrityRevListVersion != [CurrentVersion],请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 和 MBI 资产。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题。
    • SecureBootEnabled:启用安全启动后,用于启动计算机的核心组件必须具有由制造设备的组织信任的正确加密签名。 UEFI 固件在允许计算机启动之前验证此要求。 如果任何文件被篡改并破坏其签名,则系统将无法启动。

      如果 SecureBootEnabled = 1 (True) ,则允许访问。

      如果 SecurebootEnabled = 0 (False) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 允许基于评估时存在的其他数据点的条件访问。 例如,运行状况证书上的其他属性,或设备过去的活动和信任历史记录。
      • 执行上述操作之一,并将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • BootDebuggingEnabled:启用调试的启动指向开发和测试中使用的设备。 用于测试和开发的设备通常不太安全:设备可能运行不稳定的代码,或者配置为满足测试和开发所需的安全限制。

      可以在 WMI 或 PowerShell 脚本中使用以下命令来禁用或启用启动调试:

      • 若要禁用启动调试, 请键入bcdedit.exe /set {current} bootdebug off
      • 若要启用启动调试,请键入 bcdedit.exe /set {current} bootdebug

      如果 BootdebuggingEnabled = 0 (False) ,则允许访问。

      如果 BootDebuggingEnabled = 1 (True) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
      • 触发纠正措施,例如使用 WMI 或 PowerShell 脚本启用 VSM。
    • OSKernelDebuggingEnabled:OSKernelDebuggingEnabled 指向开发和测试中使用的设备。 用于测试和开发的设备通常不太安全:它们可能运行不稳定的代码,或者配置为测试和开发所需的安全限制更少。

      如果 OSKernelDebuggingEnabled = 0 (False) ,则允许访问。

      如果 OSKernelDebuggingEnabled = 1 (True) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题。
    • CodeIntegrityEnabled:启用代码完整性后,代码执行仅限于完整性验证代码。

      代码完整性是每次将驱动程序或系统文件加载到内存中时验证其完整性的功能。 代码完整性检测是否正在将未签名的驱动程序或系统文件加载到内核中,或者系统文件是否已由具有管理员权限的用户帐户运行的恶意软件修改。

      在基于 x64 的操作系统版本上,内核模式驱动程序必须经过数字签名。

      如果 CodeIntegrityEnabled = 1 (True) ,则允许访问。

      如果 CodeIntegrityEnabled = 0 (False) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 允许基于评估时存在的其他数据点的条件访问。 例如,运行状况证书上的其他属性,或设备过去的活动和信任历史记录。
      • 执行上述操作之一,并将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • TestSigningEnabled:启用测试签名后,设备在启动期间不会强制实施签名验证,并允许未签名的驱动程序 ((如未签名的 UEFI 模块)) 在启动期间加载。

      可以在 WMI 或 PowerShell 脚本中使用以下命令禁用或启用测试签名:

      • 若要禁用启动调试,请键入 bcdedit.exe /set {current} testigning off
      • 若要启用启动调试, 请键入bcdedit.exe /set {current} testigning

      如果 TestSigningEnabled = 0 (False) ,则允许访问。

      如果 TestSigningEnabled = 1 (True) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 和 MBI 资产。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
      • 触发纠正措施,例如使用 WMI 或 PowerShell 脚本启用测试签名。
    • SafeMode:安全模式是 Windows 的故障排除选项,它以受限状态启动计算机。 仅启动运行 Windows 所需的基本文件和驱动程序。

      如果 SafeMode = 0 (False) ,则允许访问。

      如果 SafeMode = 1 (True) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题。
    • WinPE:Windows 预安装环境 (Windows PE) 是一种具有有限服务的最小操作系统,用于准备计算机进行 Windows 安装、从网络文件服务器复制磁盘映像以及启动 Windows 安装程序。

      如果 WinPE = 0 (False) ,则允许访问。

      如果 WinPE = 1 (True) ,则限制对 Windows OS 安装所需的远程资源的访问。

    • ELAMDriverLoaded (Windows Defender) :若要使用此报告功能,必须在设备上禁用“混合恢复”。 提前启动反恶意软件 (ELAM) 在计算机启动时和第三方驱动程序初始化之前为网络中的计算机提供保护。

      在当前版本中,此属性仅监视/报告在初始启动期间是否加载了 Microsoft 第一方 ELAM (Windows Defender) 。

      如果设备预期使用第三方防病毒程序,请忽略报告的状态。

      如果设备预期使用 Windows Defender 且 ELAMDriverLoaded = 1 (True) ,则允许访问。

      如果设备预期使用 Windows Defender 且 ELAMDriverLoaded = 0 (False) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题。
    • VSMEnabled:虚拟安全模式 (VSM) 是一个容器,用于保护高价值资产免受入侵内核的影响。 VSM 需要大约 1 GB 的内存 - 它有足够的功能来运行用于所有身份验证代理的 LSA 服务。

      可以在 WMI 或 PowerShell 脚本中使用以下命令启用 VSM:

      bcdedit.exe /set {current} vsmlaunchtype auto

      如果 VSMEnabled = 1 (true) ,则允许访问。 如果 VSMEnabled = 0 (False) ,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 禁止访问 HBI 资产。
      • 触发纠正措施,例如通知技术支持团队联系所有者调查问题
    • PCRHashAlgorithmID:此属性是标识 TPM 使用的 HASH 算法的信息性属性;无需执行符合性操作。

    • BootAppSVN:此属性标识在证明设备上初始启动期间加载的启动应用程序的安全版本号

      如果报告的 BootAppSVN 等于接受的值,则允许访问。

      如果报告的 BootAppSVN 不等于接受的值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • BootManagerSVN:此属性标识在证明设备上初始启动期间加载的启动管理器的安全版本号。

      如果报告的 BootManagerSVN 等于接受的值,则允许访问。

      如果报告的 BootManagerSVN 不等于接受的值,请执行符合企业策略的下列操作之一:

      • 禁止所有访问。
      • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • TPMVersion:此属性标识在证明设备上运行的 TPM 版本。 TPMVersion 节点提供答复“1”和“2”:

      • 1 表示 TPM 规范版本 1.2
      • 2 表示 TPM 规范版本 2.0

      根据从 TPMVersion 节点收到的回复:

      • 如果报告的 TPMVersion 等于接受的值,则允许访问。
      • 如果报告的 TPMVersion 不等于接受的值,请执行符合企业策略的以下操作之一:
        • 禁止所有访问
        • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • PCR0:在 PCR[0] 中捕获的度量值通常表示启动周期之间的主机平台的一致视图。 它包含主机平台制造商提供的组件的度量值。

      企业管理员可以创建受信任的 PCR[0] 值的允许列表,将托管设备的 PCR[0] 值 (HAS) 验证和报告的值与允许列表进行比较,然后根据比较结果做出信任决策。

      如果企业没有接受的 PCR[0] 值的允许列表,则不采取任何操作。 如果 PCR[0] 等于接受的允许列表值,则允许访问。

      如果 PCR[0] 不等于任何已接受的列出值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • SBCPHash:SBCPHash 是自定义安全启动配置策略 (SBCP) 在 Windows 设备(电脑除外)中加载的指纹。

      如果 SBCPHash 不存在,或是接受的允许列表值,则允许访问。

      如果 DHA-Report 中存在 SBCPHash,并且不是允许列表的值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • CIPolicy:此属性指示控制启动环境安全性的代码完整性策略。

      如果 CIPolicy 不存在,或者是已接受的允许列表值,则允许访问。

      如果 CIPolicy 存在并且不是允许列出的值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备置于watch列表中,以更密切地监视设备的潜在风险。
    • BootRevListInfo:此属性标识在证明设备上初始启动期间加载的启动修订列表。

      如果报告的 BootRevListInfo 版本等于接受的值,则允许访问。

      如果报告的 BootRevListInfo 版本不等于接受的值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • OSRevListInfo:此属性标识在证明设备上初始启动时加载的操作系统修订列表。

      如果报告的 OSRevListInfo 版本等于接受的值,则允许访问。

      如果报告的 OSRevListInfo 版本不等于接受的值,请执行符合企业策略的以下操作之一:

      • 禁止所有访问。
      • 将设备定向到企业蜜罐,以进一步监视设备的活动。
    • HealthStatusMismatchFlags:如果 DHA-Service 检测到从设备管理解决方案接收 DHA-Data (不匹配) 的完整性问题,则显示 HealthStatusMismatchFlags 属性,以便进行验证。

      如果检测到问题,则会在 HealthStatusMismatchFlags 属性下列出受影响的 DHA 报告元素的列表。

    DHA-Report 示例

    <?xml version="1.0" encoding="utf-8"?>
    <HealthCertificateValidationResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ErrorCode="0" ProtocolVersion="0"
    xmlns="http://schemas.microsoft.com/windows/security/healthcertificate/validation/response/v3">
    <HealthCertificateProperties>
         <Issued>2016-10-21T02:12:58.6656577Z</Issued>
         <AIKPresent>false</AIKPresent>
         <ResetCount>2107533174</ResetCount>
         <RestartCount>2749041230</RestartCount>
         <DEPPolicy>0</DEPPolicy>
         <BitlockerStatus>0</BitlockerStatus>
         <BootManagerRevListVersion>0</BootManagerRevListVersion>
         <CodeIntegrityRevListVersion>0</CodeIntegrityRevListVersion>
         <SecureBootEnabled>false</SecureBootEnabled>
         <BootDebuggingEnabled>false</BootDebuggingEnabled>
         <OSKernelDebuggingEnabled>false</OSKernelDebuggingEnabled>
         <CodeIntegrityEnabled>true</CodeIntegrityEnabled>
         <TestSigningEnabled>true</TestSigningEnabled>
         <SafeMode>false</SafeMode>
         <WinPE>false</WinPE>
         <ELAMDriverLoaded>true</ELAMDriverLoaded>
         <VSMEnabled>false</VSMEnabled>
         <PCRHashAlgorithmID>0</PCRHashAlgorithmID>
         <BootAppSVN>1</BootAppSVN>
         <BootManagerSVN>1</BootManagerSVN>
         <TpmVersion>2</TpmVersion>
         <PCR0>4ACCBE0ADB9627FFD6285C2E06EC5AC59ABF62C7</PCR0>
         <CIPolicy>00000000000001001A000B00200000005300690050006F006C006900630079002E007000370062000000A4BF7EF05585876A61CBFF7CAE8123BE756D58B1BBE04F9719D15D6271514CF5</CIPolicy>
         <BootRevListInfo>005D447A7CC6D101200000000B00CBB56E8B19267E24A2986C4A616CCB58B4D53F6020AC8FD5FC205C20F2AB00BC</BootRevListInfo>
         <OSRevListInfo>8073EEA7F8FAD001200000000B00A8285B04DE618ACF4174C59F07AECC002D11DD7D97FA5D464F190C9D9E3479BA</OSRevListInfo>
     </HealthCertificateProperties>
    </HealthCertificateValidationResponse>
    

    HealthAttestation CSP 状态和错误代码

    错误代码 错误名称 错误描述
    0 HEALTHATTESTATION_CERT_RETRIEVAL_UNINITIALIZED 此状态是从未参与 DHA 会话的设备的初始状态。
    1 HEALTHATTESTATION_CERT_RETRIEVAL_REQUESTED 此状态表示 MDM 客户端在 VerifyHealth 节点上的 Exec 调用已触发,现在 OS 正尝试从 DHA-Server 检索 DHA-EncBlob。
    2 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED 此状态表示设备无法从 DHA-Server 检索 DHA-EncBlob。
    3 HEALTHATTESTATION_CERT_RETRIEVAL_COMPLETE 此状态表示设备已成功从 DHA-Server 检索 DHA-EncBlob。
    4 HEALTHATTESTATION_CERT_RETRIEVAL_PCR_FAIL 在 Windows 10 版本 1607 中已弃用。
    5 HEALTHATTESTATION_CERT_RETRIEVAL_GETQUOTE_FAIL DHA-CSP 未能获取声明报价。
    6 HEALTHATTESTATION_CERT_RETRIEVAL_DEVICE_NOT_READY DHA-CSP 未能打开 Microsoft 平台加密提供程序的句柄。
    7 HEALTHATTESTATION_CERT_RETRIEVAL_WINDOWS_AIK_FAIL DHA-CSP 在检索 Windows AIK 时失败
    8 HEALTHATTESTATION_CERT_RETRIEVAL_FROM_WEB_FAIL 在 Windows 10 版本 1607 中已弃用。
    9 HEALTHATTESTATION_CERT_RETRIEVAL_INVALID_TPM_VERSION 无效的 TPM 版本 (TPM 版本不是 1.2 或 2.0)
    10 HEALTHATTESTATION_CERT_RETRIEVAL_GETNONCE_FAIL 在注册表中找不到 Nonce。
    11 HEALTHATTESTATION_CERT_RETRIEVAL_GETCORRELATIONID_FAIL 在注册表中找不到相关 ID。
    12 HEALTHATTESTATION_CERT_RETRIEVAL_GETCERT_FAIL 在 Windows 10 版本 1607 中已弃用。
    13 HEALTHATTESTATION_CERT_RETRIEVAL_GETCLAIM_FAIL 在 Windows 10 版本 1607 中已弃用。
    14 HEALTHATTESTATION_CERT_RETRIEVAL_ENCODING_FAIL 编码函数失败。 (极不可能的方案)
    15 HEALTHATTESTATION_CERT_RETRIEVAL_ENDPOINTOVERRIDE_FAIL 在 Windows 10 版本 1607 中已弃用。
    16 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_LOAD_XML DHA-CSP 无法加载从 DHA-Service 接收的有效负载。
    17 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_CORRUPT_XML DHA-CSP 收到了来自 DHA-Service 的损坏响应。
    18 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_EMPTY DHA-CSP 收到了来自 DHA-Service 的空响应。
    19 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_DECRYPT_AES_EK DHA-CSP 未能从 EK 质询中解密 AES 密钥。
    20 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_DECRYPT_CERT_AES_EK DHA-CSP 未能使用 AES 密钥解密运行状况证书。
    21 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_EXPORT_AIKPUB DHA-CSP 未能导出 AIK 公钥。
    22 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_CREATE_CLAIMAUTHORITYONLY DHA-CSP 尝试使用 AIK 证明数据创建声明失败。
    23 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_APPEND_AIKPUB DHA-CSP 未能将 AIK Pub 追加到请求 Blob。
    24 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_APPEND_AIKCERT DHA-CSP 未能将 AIK 证书追加到请求 Blob。
    25 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_INIT_HTTPHANDLE DHA-CSP 未能获取会话句柄。
    26 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_GETTARGET_HTTPHANDLE DHA-CSP 无法连接到 DHA-Service。
    27 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_CREATE_HTTPHAND DHA-CSP 未能创建 HTTP 请求句柄。
    28 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_SET_INTERNETOPTION DHA-CSP 未能设置选项。
    29 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_ADD_REQUESTHEADERS DHA-CSP 未能添加请求标头。
    30 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_SEND_REQUEST DHA-CSP 无法发送 HTTP 请求。
    31 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_RECEIVE_RESPONSE DHA-CSP 未能收到来自 DHA-Service 的响应。
    32 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_QUERY_HEADERS DHA-CSP 在尝试获取 HTTP 状态代码时无法查询标头。
    33 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_EMPTY_RESPONSE DHA-CSP 收到来自 DHA-Service 的空响应,即使 HTTP 状态正常也是如此。
    34 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_MISSING_RESPONSE DHA-CSP 收到来自 DHA-Service 的空响应以及 HTTP 错误代码。
    35 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_IMPERSONATE_USER DHA-CSP 无法模拟用户。
    36 HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_ACQUIRE_PDCNETWORKACTIVATOR 当设备处于连接待机模式时,DHA-CSP 无法获取网络通信所需的 PDC 激活器。
    0xFFFF HEALTHATTESTATION_CERT_RETRIEVAL_FAILED_UNKNOWN DHA-CSP 由于原因不明而失败,此错误不太可能发生。
    400 Bad_Request_From_Client DHA-CSP 收到了格式错误的 () 证明请求。
    404 Endpoint_Not_Reachable DHA-CSP 无法访问 DHA-Service

    安全注意事项

    DHA 锚定了对 TPM 及其度量值的信任。 如果 TPM 度量可能受到欺骗或篡改,DHA 无法为该设备提供设备运行状况的任何保证。

    有关详细信息,请参阅 电脑客户端 TPM 认证

    配置服务提供程序参考