你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Azure 证明适用于 .NET 的客户端库 - 版本 1.0.0

Microsoft Azure 证明 (MAA) 服务是一种统一的解决方案,用于远程验证平台的可信度和在其中运行的二进制文件的完整性。 该服务支持对受信任的平台模块 (TPM) 支持的平台的证明,以及对受信任执行环境 (TEE) 的状态进行证明的功能,例如 Intel® Software Guard Extensions (SGX) enclave 和基于虚拟化的安全性 (VBS) enclave。

证明是演示如何在受信任的平台上正确实例化软件二进制文件的过程。 然后,远程信赖方可以确信只有此类软件在受信任的硬件上运行。 Azure 证明是一个统一的面向客户的认证服务和框架。

Azure 证明使用先进的安全范例,如 Azure 机密计算和智能边缘保护。 客户一直在请求独立验证计算机位置、计算机上的虚拟机 (VM) 状态以及在该 VM 上运行 enclave 的环境的功能。 Azure 证明将满足这些请求以及诸多其他客户请求。

Azure 证明从计算实体接收证据,将它们转换为一组声明,根据可配置的策略对其进行验证,并为基于声明的应用(例如信赖方和审核机构)生成加密证明。

注意:这是 Microsoft Azure 证明 服务的预览版 SDK。 它提供了访问Azure 证明服务的所有基本功能,应将其视为“原样”,并且将来可能会发生更改,这可能会破坏与以前版本的兼容性。

源代码 | 包 (NuGet) | API 参考文档 | 产品文档

入门

先决条件

  • Azure 订阅。 若要使用 Azure 服务(包括 Microsoft Azure 证明 服务),需要订阅。 如果没有现有的 Azure 帐户,可以在创建帐户时注册免费试用版或使用 Visual Studio 订阅权益。
  • 现有的 Azure 证明 实例,也可以使用每个 Azure 区域中提供的“共享提供程序”。 如果需要创建Azure 证明服务实例,可以使用 Azure 门户或 Azure CLI

安装包

使用 NuGet 安装适用于 .NET 的 Microsoft Azure 证明 客户端库:

dotnet add package Azure.Security.Attestation --prerelease

验证客户端

若要与 Microsoft Azure 证明 服务交互,需要创建证明客户端证明管理客户端类的实例。 需要一个 证明实例 URL(可能在门户中显示为“DNS 名称”),客户端 密码凭据 (客户端 ID、客户端密码、租户 ID) 来实例化客户端对象。

本入门部分将使用客户端机密凭据身份验证,但你可以找到使用 Azure 标识进行身份验证的更多方法。 若要使用如下所示的 DefaultAzureCredential 提供程序或 Azure SDK 提供的其他凭据提供程序,应安装 Azure.Identity 包:

dotnet add package Azure.Identity

创建/获取凭据

使用以下 Azure CLI 代码片段创建/获取客户端机密凭据。

  • 创建服务主体并配置其对 Azure 资源的访问权限:

    az ad sp create-for-rbac -n <your-application-name> --skip-assignment
    

    输出:

    {
        "appId": "generated-app-ID",
        "displayName": "dummy-app-name",
        "name": "http://dummy-app-name",
        "password": "random-password",
        "tenant": "tenant-ID"
    }
    
  • 记下服务主体 objectId

    az ad sp show --id <appId> --query objectId
    

    输出:

    "<your-service-principal-object-id>"
    
  • 使用上面返回的凭据设置 AZURE_CLIENT_ID (appId) 、 AZURE_CLIENT_SECRET (密码) ,以及 AZURE_TENANT_ID (租户) 环境变量。 以下示例演示了在 Powershell 中执行此操作的方法:

    $Env:AZURE_CLIENT_ID="generated-app-ID"
    $Env:AZURE_CLIENT_SECRET="random-password"
    $Env:AZURE_TENANT_ID="tenant-ID"
    

有关 Azure 标识 API 及其使用方法的详细信息,请参阅 Azure 标识客户端库

关键概念

此预览版 SDK 中提供了四个主要的功能系列:

Microsoft Azure 证明服务以两种不同的模式运行:“独立”和“AAD”。 当服务在“独立”模式下运行时,客户需要提供其身份验证凭据以外的其他信息,以验证他们是否有权修改证明实例的状态。

最后,提供 Microsoft Azure 证明 服务的每个区域都支持一个“共享”实例,该实例可用于证明 SGX enclave,只需根据 azure 基线进行验证, (没有策略应用于共享实例) 。 TPM 证明在共享实例中不可用。 虽然共享实例需要 AAD 身份验证,但它没有任何 RBAC 策略 - 任何具有有效 AAD 持有者令牌的客户都可以使用共享实例进行证明。

证明

SGX 或 TPM 证明是验证从受信任的执行环境收集的证据的过程,以确保它同时满足该环境的 Azure 基线和应用于该环境的客户定义策略。

证明服务令牌签名证书发现和验证

Azure 证明服务的核心操作保证之一是服务“在 TCB 外操作”。 换句话说,Microsoft 操作员无法篡改服务的操作,也不可能损坏从客户端发送的数据。 为了确保此保证,证明服务的核心在 Intel (tm) SGX enclave 中运行。

为了允许客户验证操作是否确实在 enclave 内执行,来自证明服务的大多数响应都以 JSON Web 令牌进行编码,该令牌由证明服务的 enclave 中保存的密钥签名。

此令牌将由 MAA 服务为指定实例颁发的签名证书进行签名。

如果 MAA 服务实例在服务在 SGX enclave 中运行的区域运行,则可以使用 oe_verify_attestation_certificate API 验证服务器颁发的证书。

对象AttestationResponse包含两个main属性: TokenValue。 属性 Token 包含证明服务返回的完整令牌, Value 属性包含 JSON Web 令牌响应的正文。

策略管理

每个证明服务实例都应用了一个策略,该策略定义了客户定义的其他条件。

有关证明策略的详细信息,请参阅 证明策略

策略管理证书管理

当证明实例在“独立”模式下运行时,创建该实例的客户将在创建该实例时提供策略管理证书。 所有策略修改操作都要求客户使用现有策略管理证书之一对策略数据进行签名。 策略管理证书管理 API 使客户端能够“滚动”策略管理证书。

隔离模式和 AAD 模式

每个 Microsoft Azure 证明 服务实例在“AAD”模式或“独立”模式下运行。 当 MAA 实例在 AAD 模式下运行时,这意味着创建证明实例的客户允许 Azure Active Directory 和 Azure 基于角色的访问控制策略来验证对证明实例的访问。

AttestationType

Microsoft Azure 证明服务支持根据环境证明不同类型的证据。 目前,MAA 支持以下受信任的执行环境:

  • OpenEnclave - 在 SGX Enclave 中运行代码的 Intel (tm) 处理器,其中证明证据是使用 OpenEnclave oe_get_reportoe_get_evidence API 收集的。
  • SgxEnclave - Intel (tm) 处理器,在 SGX Enclave 中运行代码,其中证明证据是使用 Intel SGX SDK 收集的。
  • Tpm - 基于虚拟化的安全环境,其中处理器的受信任平台模块用于提供证明证据。

运行时数据和 Inittime 数据

RuntimeData 是指呈现给 Intel SGX 报价生成逻辑或 oe_get_report/oe_get_evidence API 的数据。 Azure 证明服务将验证 SGX Quote/OE Report/OE Evidence 中字段的前 32 个字节report_data是否与 RuntimeData 的 SHA256 哈希匹配。

InitTime 数据是指用于配置要证明的 SGX enclave 的数据。

请注意,Azure DCsv2 系列 虚拟机不支持 InitTime 数据。

线程安全

我们保证所有客户端实例方法都是线程安全的,并且彼此独立 (准则) 。 这可确保重用客户端实例的建议始终是安全的,即使在线程之间也是如此。

其他概念

客户端选项 | 访问响应 | 长时间运行的操作 | 处理失败 | 诊断 | 嘲笑 | 客户端生存期

示例

创建客户端实例

在 uri endpoint处创建证明客户端的实例。

var options = new AttestationClientOptions();
return new AttestationClient(new Uri(endpoint), new DefaultAzureCredential(), options);

获取证明策略

方法 GetPolicy 从服务中检索证明策略。 证明策略基于每个证明类型进行实例化, AttestationType 参数定义要检索的类型。

var client = new AttestationAdministrationClient(new Uri(endpoint), new DefaultAzureCredential());

AttestationResponse<string> policyResult = await client.GetPolicyAsync(AttestationType.SgxEnclave);
string result = policyResult.Value;

为指定的证明类型设置证明策略

如果证明服务实例在独立模式下运行,SetPolicy API 需要提供签名证书 (和私钥) 可用于验证调用方是否有权修改证明实例上的策略。 如果服务实例在 AAD 模式下运行,则签名证书和密钥是可选的。

在幕后,SetPolicy API 基于发送到证明服务的策略文档和签名信息创建 JSON Web 令牌

string attestationPolicy = "version=1.0; authorizationrules{=> permit();}; issuancerules{};";

X509Certificate2 policyTokenCertificate = new X509Certificate2(<Attestation Policy Signing Certificate>);
AsymmetricAlgorithm policyTokenKey = <Attestation Policy Signing Key>;

var setResult = client.SetPolicy(AttestationType.SgxEnclave, attestationPolicy, new AttestationTokenSigningKey(policyTokenKey, policyTokenCertificate));

在证明服务的 enclave 收到策略文档之前,客户端需要能够验证证明策略文档是否未修改。

PolicyResult 中提供了两个属性,可用于验证服务是否收到了策略文档:

  • PolicySigner - 如果 SetPolicy 调用包含签名证书,则这是在调用时 SetPolicy 提供的证书。 如果未设置策略签名者,则此值为 null。
  • PolicyTokenHash - 这是发送到服务的 JSON Web 令牌 的哈希。

若要验证哈希,客户端可以生成证明令牌并验证从该令牌生成的哈希:

// The SetPolicyAsync API will create an AttestationToken signed with the TokenSigningKey to transmit the policy.
// To verify that the policy specified by the caller was received by the service inside the enclave, we
// verify that the hash of the policy document returned from the Attestation Service matches the hash
// of an attestation token created locally.
TokenSigningKey signingKey = new TokenSigningKey(<Customer provided signing key>, <Customer provided certificate>)
var policySetToken = new AttestationToken(
    BinaryData.FromObjectAsJson(new StoredAttestationPolicy { AttestationPolicy = attestationPolicy }),
    signingKey);

using var shaHasher = SHA256Managed.Create();
byte[] attestationPolicyHash = shaHasher.ComputeHash(Encoding.UTF8.GetBytes(policySetToken.Serialize()));

Debug.Assert(attestationPolicyHash.SequenceEqual(setResult.Value.PolicyTokenHash.ToArray()));

证明 SGX Enclave

AttestSgxEnclave使用 方法来证明 SGX enclave。

客户在与加密环境交互时面临的核心挑战之一是,如何确保能够可靠地与环境中运行的代码通信, (“enclave 代码”) 。

此问题的一种解决方案是所谓的“安全密钥发布”,这是一种模式,它支持与 enclave 代码进行此类通信。

为了实现“安全密钥发布”模式,enclave 代码会生成一个临时非对称密钥。 然后,它会将密钥的公共部分序列化为某种格式, (可能是 JSON Web 密钥、PEM 或某种其他序列化格式) 。

然后,enclave 代码会计算公钥的 SHA256 值,并将其作为输入传递给代码,该代码为 OpenEnclave 生成 SGX 报价 (,即 oe_get_evidenceoe_get_report) 。

然后,客户端将 SGX 引号和序列化密钥发送到证明服务。 证明服务将验证引号,并确保密钥的哈希存在于引号中,并将颁发“证明令牌”。

然后,客户端可以将包含序列化密钥) 的证明令牌 (发送到第三方“信赖方”。 然后,信赖方验证证明令牌是由证明服务创建的,因此序列化密钥可用于加密“信赖方”持有的一些数据,以发送到服务。

此示例演示了一种常见模式,即调用证明服务以检索与请求关联的证明令牌。

此示例假定你有一个使用终结点的基 URI 配置的现有 AttestationClient 对象。 它还假设你有一个 SGX 报价 (binaryQuote) 从要证明的 SGX enclave 中生成,“运行时数据” (runtimeData SGX 报价中引用的) 。

// Collect quote and runtime data from an SGX enclave.
// For the "Secure Key Release" scenario, the runtime data is normally a serialized asymmetric key.
// When the 'quote' (attestation evidence) is created specify the SHA256 hash of the runtime data when
// creating the evidence.
//
// When the generated evidence is created, the hash of the runtime data is included in the
// secured portion of the evidence.
//
// The Attestation service will validate that the Evidence is valid and that the SHA256 of the RuntimeData
// parameter is included in the evidence.
AttestationResponse<AttestationResult> attestationResult = client.AttestSgxEnclave(new AttestationRequest
{
    Evidence = BinaryData.FromBytes(binaryQuote),
    RuntimeData = new AttestationData(BinaryData.FromBytes(binaryRuntimeData), false),
});

// At this point, the EnclaveHeldData field in the attestationResult.Value property will hold the
// contain the input binaryRuntimeData.

// The token is now passed to the "relying party". The relying party will validate that the token was
// issued by the Attestation Service. It then extracts the asymmetric key from the EnclaveHeldData field.
// The relying party will then Encrypt it's "key" data using the asymmetric key and transmits it back
// to the enclave.
var encryptedData = SendTokenToRelyingParty(attestationResult.Token);

// Now the encrypted data can be passed into the enclave which can decrypt that data.

有关如何执行证明令牌验证的其他信息,请参阅 MAA 服务证明示例

检索令牌证书

使用 GetSigningCertificatesAsync 检索可用于验证从证明服务返回的令牌的证书。

var client = GetAttestationClient();

IReadOnlyList<AttestationSigner> signingCertificates = (await client.GetSigningCertificatesAsync()).Value;

疑难解答

大多数证明服务操作会在失败时引发 RequestFailedException ,并具有有用的 ErrorCodes。 其中许多错误是可恢复的。

try
{
    AttestationResponse<AttestationResult> attestationResult = client.AttestSgxEnclave(new AttestationRequest
    {
        Evidence = BinaryData.FromBytes(binaryQuote),
        RuntimeData = new AttestationData(BinaryData.FromBytes(binaryRuntimeData), false),
    });
}
catch (RequestFailedException ex)
    when (ex.ErrorCode == "InvalidParameter")
    {
    // Ignore invalid quote errors.
    }

在此处找到 MAA 服务的其他故障排除信息

后续步骤

有关 Microsoft Azure 证明服务的详细信息,请参阅我们的文档页

贡献

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息 ,请访问参与者许可协议站点

提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 对所有存储库执行一次这样的操作。

此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅行为准则常见问题解答;若有其他任何问题或意见,请联系 opencode@microsoft.com

有关构建、测试和参与这些库的详细信息,请参阅 CONTRIBUTING.md

曝光数