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

Azure 证明 Python 客户端库 - 版本 1.0.0

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

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

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

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

此包已经过 Python 2.7、3.6 到 3.9 的测试。

有关 Azure 库的更完整视图,请参阅 适用于 Python 的 Azure SDK 发布页

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

入门

先决条件

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

安装包

使用 PyPI 安装适用于 Python 的 Azure 证明 客户端库:

pip install azure-security-attestation

验证客户端

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

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

pip install 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”。 当服务在“独立”模式下运行时,客户需要提供身份验证凭据以外的其他信息,以验证他们是否有权修改证明实例的状态。

最后,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 验证服务器颁发的证书。

策略管理

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

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

策略管理证书管理

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

独立模式和 AAD 模式

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

AttestationType

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 的数据。 如果证明 API 的调用方提供了属性runtime_data,则 Azure 证明 服务将验证 SGX 报价/OE 报告/OE 证据中字段的前 32 个字节report_data是否与 的 runtime_dataSHA256 哈希匹配。

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

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

其他概念

示例

创建客户端实例

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

attest_client = AttestationClient(
    endpoint=base_uri,
    credential=DefaultAzureCredential())

获取证明策略

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

policy, token = attest_client.get_policy(AttestationType.SGX_ENCLAVE)
print('Instance SGX policy: ', policy)
print('Token: ', token)

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

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

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

policy_set_response = attest_client.set_policy(AttestationType.SGX_ENCLAVE,
    attestation_policy,
    signing_key=key,
    signing_certificate=signing_certificate)
new_policy, _ = attest_client.get_policy(AttestationType.SGX_ENCLAVE)
# `new_policy` will equal `attestation_policy`.

如果服务实例在 AAD 模式下运行,则可以简化对 set_policy 的调用:

policy_set_response = attest_client.set_policy(AttestationType.SGX_ENCLAVE,            
    attestation_policy)
# Now retrieve the policy which was just set.
new_policy, _ = attest_client.get_policy(AttestationType.SGX_ENCLAVE)

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

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

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

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

from cryptography.hazmat.primitives import hashes

expected_policy = AttestationPolicyToken(
    attestation_policy,
    signing_key=key,
    signing_certificate=signing_certificate)
hasher = hashes.Hash(hashes.SHA256())
hasher.update(expected_policy.serialize().encode('utf-8'))
expected_hash = hasher.finalize()

# `expected_hash` will exactly match `policy_set_response.policy_token_hash`

证明 SGX Enclave

使用 attest_sgx_enclave 方法来证明 SGX enclave。

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

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

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

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

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

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

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

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

response, token = attest_client.attest_sgx_enclave(quote, runtime_data=runtime_data)

此时,attestationResult 中的 enclave_held_data 属性将保存输入二进制runtime_data。

令牌现在将传递给“信赖方”。 信赖方将验证令牌是否由证明服务颁发。 然后,它从 EnclaveHeldData 字段中提取非对称密钥。 然后,信赖方将使用非对称密钥加密其“密钥”数据,并将其传输回 enclave。

encrypted_data = send_token_to_relying_party(attestationResult.Token)

现在,加密的数据可以传递到可以解密该数据的 enclave。

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

检索令牌证书

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

signers = attest_client.get_signing_certificates()
for signer in signers:
    from cryptography.hazmat.backends import default_backend
    cert = cryptography.x509.load_pem_x509_certificate(signer.certificates[0].encode('ascii'), backend=default_backend())
    print('Cert  iss:', cert.issuer, '; subject:', cert.subject)

疑难解答

大多数证明服务操作都会引发 Azure Core 中定义的异常。 证明服务 API 会在失败时引发 , HttpResponseError 并显示有用的错误代码。 其中许多错误是可恢复的。

try:
    response, _ = attest_client.attest_sgx_enclave(
        quote,
        runtime_data=AttestationData(runtime_data, is_json=False))
except HttpResponseError as ex:
    # Ignore invalid quote errors.
    if ex.error == "InvalidParameter":
        pass
}

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

后续步骤

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

贡献

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

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

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

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

提供反馈

如果遇到任何 bug 或有建议,请在项目的“ 问题 ”部分中提交问题。

曝光数