跳转到主要内容

Microsoft Azure Attestation Client Library for Python

项目描述

Azure Attestation客户端库,用于Python

Microsoft Azure Attestation (MAA) 服务是一个统一的解决方案,用于远程验证平台的可信度和运行在其内部二进制文件的完整性。该服务支持由可信平台模块 (TPM) 支持的平台进行证明,同时具备证明可信执行环境 (TEE) 状态的能力,如英特尔软件保护扩展 (SGX) 容器和基于虚拟化的安全 (VBS) 容器。

证明是一个过程,用于证明软件二进制文件已正确实例化在可信平台上。远程依赖方可以据此获得信心,认为仅在可信硬件上运行了此类预期的软件。Azure Attestation是一个统一的面向客户的服务和证明框架。

Azure Attestation使领先的网络安全范式,如Azure机密计算和智能边缘保护成为可能。客户一直在请求独立验证机器的位置、该机器上虚拟机 (VM) 的状态以及在该VM上运行的容器环境的能力。Azure Attestation将赋予这些和许多其他客户请求的能力。

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

此包已在 Python 2.7、3.6 至 3.9 上进行测试。

要获取 Azure 库的更完整视图,请参阅 Azure SDK for Python 发布页面

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

入门指南

先决条件

  • Azure 订阅。要使用 Azure 服务,包括 Azure Attestation 服务,您需要一个订阅。如果您没有现有的 Azure 账户,您可以在创建账户时注册一个 免费试用版 或使用您的 Visual Studio 订阅 优惠。
  • 现有的 Azure Attestation 实例,或者您可以使用每个 Azure 区域中可用的 "共享提供者"。如果您需要创建 Azure Attestation 服务实例,您可以使用 Azure Portal 或 Azure CLI

安装包

使用 PyPI 安装 Azure Attestation 客户端库 for Python

pip install azure-security-attestation

验证客户端

为了与 Azure Attestation 服务交互,您需要创建 Attestation ClientAttestation Administration Client 类的实例。您需要一个 验证端点,您可能会在门户中看到它作为 "验证 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 Identity 客户端库

关键概念

此预览 SDK 中提供了四个主要功能家族

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

最后,Azure Attestation服务可用的每个区域都支持一个“共享”实例,可以用来验证只需与Azure基准进行验证的SGX enclave(对共享实例不应用任何策略)。共享实例中不可用TPM attestation。虽然共享实例需要AAD身份验证,但它没有任何RBAC策略 - 拥有有效AAD载体令牌的任何客户都可以使用共享实例进行认证。

认证

SGX或TPM认证是从可信执行环境中收集证据以验证其是否满足该环境Azure基准以及客户对该环境应用的策略的过程。

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

Azure Attestation服务的一个核心操作保证是该服务操作“超出TCB操作”。换句话说,微软操作员无法篡改服务的操作或损坏客户端发送的数据。为了确保这一保证,认证服务的核心在Intel(tm) SGX enclave中运行。

为了允许客户验证操作是否实际在enclave内部执行,大多数来自认证服务的响应都编码在由认证服务enclave中持有的密钥签名的JSON Web Token中。

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

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

策略管理

每个认证服务实例都应用一个策略,该策略定义了客户定义的额外标准。

有关认证策略的更多信息,请参阅认证策略

策略管理证书管理

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

隔离模式和AAD模式

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

认证类型

Azure Attestation服务支持根据环境验证不同类型的证据。目前,MAA支持以下可信执行环境:

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

运行时数据和初始化时数据

运行时数据是指呈现给Intel SGX报价生成逻辑或oe_get_report/oe_get_evidence API的数据。如果调用证明API的调用者提供了runtime_data属性,Azure证明服务将验证SGX报价/OE报告/OE证据中report_data字段的第一个32字节是否与runtime_data的SHA256哈希匹配。

初始化时数据是指用于配置正在证明的SGX安全区域的数据。

请注意,初始化时数据不支持在Azure DCv2系列虚拟机上。

其他概念

示例

创建客户端实例

在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 Token,并将其发送到证明服务。

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)

客户端需要能够验证在策略文档被证明服务安全区域接收之前,策略文档未被修改。

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

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

要验证哈希,客户端可以生成一个证明策略令牌并验证由此令牌生成的哈希

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安全区域

使用attest_sgx_enclave方法来证明SGX安全区域。

客户在与加密环境交互时面临的核心理问题是如何确保可以安全地与在环境中运行的代码(“安全区域代码”)进行通信。

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

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

然后,安全区域代码计算公钥的SHA256值,并将其作为输入传递给生成SGX Quote(对于OpenEnclave,将是oe_get_evidenceoe_get_report)的代码。

然后,客户端将SGX Quote和序列化密钥发送给认证服务。认证服务将验证Quote,并确保密钥的哈希值存在于Quote中,并颁发一个“认证令牌”。

然后,客户端可以将该认证令牌(其中包含序列化密钥)发送给第三方“依赖方”。依赖方随后将验证认证令牌是由认证服务创建的,因此可以序列化密钥来加密“依赖方”持有的某些数据,并发送给服务。

此示例展示了调用认证服务以检索与请求相关联的认证令牌的一种常见模式。

此示例假设您有一个现有的配置了端点基本URI的AttestationClient对象。它还假设您有一个从您正在认证的SGX安全区域生成的SGX Quote(quote),以及引用于SGX Quote中的“运行时数据”(runtime_data)。

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

此时,attestationResult中的enclave_held_data属性将包含输入的二进制运行时数据。

现在,令牌传递给“依赖方”。依赖方将验证该令牌是由认证服务签发的。然后,它从EnclaveHeldData字段中提取非对称密钥。依赖方然后将其“密钥”数据使用非对称密钥加密,并将其发送回安全区域。

encrypted_data = send_token_to_relying_party(attestationResult.Token)

现在,加密数据可以传递到安全区域,该区域可以解密该数据。

有关如何执行认证令牌验证的更多信息,请参阅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-bot将自动确定您是否需要提供CLA,并相应地装饰PR(例如,标签,注释)。只需遵循机器人提供的说明即可。您只需在整个使用我们的CLA的存储库中这样做一次。

此项目已采用Microsoft开源代码行为准则。有关更多信息,请参阅行为准则FAQ或联系opencode@microsoft.com以获取任何附加问题或评论。

请参阅CONTRIBUTING.md以获取有关构建、测试和贡献这些库的详细信息。

提供反馈

如果您遇到任何错误或有所建议,请在此项目的问题部分提交问题。

Impressions

发行历史

1.0.0 (2021-07-06)

新增功能

示例清理 - 示例现在使用DefaultAzureCredential代替ClientSecretCredentials。

破坏性更改

  • TPM证明接受一个JSON字符串参数,并返回一个JSON字符串参数。
    • 移除了TPMAttestationRequest和TPMAttestationResponse类型。
  • 从AttestationResult类型中移除了confirmation属性。
  • 移除了AttestationSigningKey类型,用signing_key和signing_certificate关键字参数替换。
  • SDK现在接受和返回的所有证书和密钥都是PEM编码的字符串,而不是DER编码的字节序列数组,以便于操作和互操作性。
  • 移除了AttestationResponse类型,token值合并到AttestationResult、PolicyResult等。
  • 移除了TokenValidationOptions类型,并将验证选项合并到API的关键字参数中,这些API用于验证返回的令牌。这些关键字参数也可以在客户端类中指定,以简化单个API调用。
  • 将构造函数中的instance_url参数重命名为endpoint。
  • 将AttestationResult中的许多可选字段改为非可选。
  • 将AttestationToken._validate_token改为仅限内部使用,并现在返回None。
    • 现在,如果调用者提供的validation_callback在无效令牌上必须抛出异常,而不是返回False。
  • 移除了AttestationData类型,attest_xxx API现在接受两组参数:inittime_data/inittime_json和runtime_data/runtime_json。如果设置了_json值,则参数值是UTF8编码的JSON值的数组,如果设置了_data值,则参数值是字节数组。
  • get_policy API现在返回一个Tuple[str, AttestationToken],以简化消费体验。
  • get_policy_management_certificates API也返回一个Tuple[list[list[string]], AttestationToken],以简化消费体验。注意,列表中的每个条目都是一个PEM编码的X.509证书。

如果您关心证明策略和令牌,调用attest API可以编写以下代码:

policy, token = attest_client.get_policy(AttestationType.SGX_ENCLAVE)

如果您只关心策略,可以编写以下任何一种:

policy, _ = attest_client.get_policy(AttestationType.SGX_ENCLAVE)

或者

policy = attest_client.get_policy(AttestationType.SGX_ENCLAVE)[0]

或者

response = attest_client.get_policy(AttestationType.SGX_ENCLAVE)
policy = response[0]
  • AttestationToken类不再继承自Generic。
  • attest_sgx_enclave和attest_openenclave API现在返回一个AttestationResult和AttestationToken的元组,类似于get_policy API。
  • set_policy、reset_policy、add_policy_management_certificate和remove_policy_management_certificate API都返回一个元组。
  • AttestationToken.get_body() API已重命名为AttestationToken.body()。
  • 将一些与时间相关的属性重命名,以保持与keyvault的使用一致。
    • AttestationToken上的expiration_time属性已重命名为expires。
    • AttestationToken上的issuance_time属性已重命名为issued_on。
    • AttestationToken上的not_before_time属性已重命名为not_before。
  • 已移除StoredAttestationPolicy模型类型。要验证证明策略哈希,请使用AttestationPolicyToken模型对象。
  • get_openidmetadata API已重命名为get_open_id_metadata。

1.0.0b4 (2021-06-08)

新增功能

  • 添加了reset_policy API。
  • 添加了模型。
  • 文档清理。

破坏性更改

  • 创建StoredAttestationPolicy模型类型意味着构造函数的attestation_policy关键字参数已被替换为positional policy参数。因此,此更改导致以下代码:
StoredAttestationPolicy(attestation_policy=str(attestation_policy).encode('utf-8')))

更改

StoredAttestationPolicy(attestation_policy)
  • AttestationResult 类型的几个参数被重命名,与 AttestationToken 共享的几个参数已被删除。总的来说,命名更改删除了一些协议特定元素,并用更友好的名称替换了它们。最后,弃用的属性已被从 AttestationResult 中删除。

    完整更改集

    • iss 更名为 issuer
    • cnf 更名为 confirmation
    • jti 更名为 unique_identifier
    • iat 已删除
    • exp 已删除
    • nbf 已删除
    • deprecated_version 已删除
    • deprecated_is_debuggable 已删除
    • deprecated_sgx_collateral 已删除
    • deprecated_enclave_held_data 已删除
    • deprecated_enclave_held_data2 已删除
    • deprecated_product_id 已删除
    • deprecated_mr_enclave 已删除
    • deprecated_mr_signer 已删除
    • deprecated_svn 已删除
    • deprecated_tee 已删除
    • deprecated_policy_signer 已删除
    • deprecated_policy_hash 已删除
    • deprecated_rp_data 已删除

    如果客户需要直接访问删除或重命名的字段,他们可以使用 AttestationResponse 对象的 get_body 方法。

      if response.token.get_body().deprecated_tee != 'sgx':
          print("Unexpected tee claim in token")
    

1.0.0b2 (2021-05-11)

新增功能

  • 认证服务的 Track 2 SDK 的初步实现。

破坏性更改

  • API 界面的完整重新实现,遵循认证服务已建立的 API 模式。

1.0.0b1 (2021-01-15)

MAA 数据平面 SDK 的初始早期预览版,展示了机器生成的 MAA API 的使用。

  • 初始版本

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分发

azure-security-attestation-1.0.0.zip (1.4 MB 查看散列)

上传时间

构建分发

azure_security_attestation-1.0.0-py2.py3-none-any.whl (82.9 kB 查看散列)

上传时间 Python 2 Python 3

由以下赞助

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面