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

Azure 证明 JavaScript 客户端库 - 版本 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 证明从计算实体接收证据,将它们转换为一组声明,根据可配置的策略对其进行验证,并为基于声明的应用(例如信赖方和审核机构)生成加密证明。

有关 Azure 库的更完整视图,请参阅 azure sdk typescript 版本

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

关键链接:

入门

目前支持的环境

有关更多详细信息,请参阅我们的支持政策

先决条件

  • Azure 订阅
  • 现有Azure 证明实例,也可以使用每个 Azure 区域中提供的“共享提供程序”。 如果需要创建Azure 证明服务实例,可以使用 Azure 门户或 Azure CLI

安装 @azure/attestation 包

使用 NPM 安装适用于 JavaScript 的 Microsoft Azure 证明 客户端库:

npm install @azure/attestation

验证客户端

若要与 Microsoft Azure 证明服务交互,需要创建证明客户端证明管理客户端类的实例。 需要一个 证明实例 URL,该 URL 要么是门户中显示的“证明 URI”,要么是共享证明提供程序之一。 还需要客户端凭据才能使用证明管理客户端或调用 attestTpm API。 客户端凭据需要 (客户端 ID、客户端密码、租户 ID) 来实例化客户端对象。

在本入门部分,我们将通过 DefaultAzureCredential 提供程序使用客户端机密凭据进行身份验证,但我们通过 @azure/标识 包提供更多的身份验证机制。 安装 @azure/identity 包:

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

最后,提供 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 包含两个主要属性: tokenvalue。 属性 token 包含证明服务返回的完整令牌, value 该属性包含 JSON Web 令牌响应的正文。

策略管理

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

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

策略管理证书管理

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

独立模式和 AAD 模式

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

AttestationType

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

  • OpenEnclave - Intel (tm) 处理器,在 SGX Enclave 中运行代码,证明证据是使用 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 数据。

其他概念

示例

创建客户端实例

使用默认 azure 凭据在 uri endpoint处创建证明客户端的实例, DefaultAzureCredential () 。

const credentials = new DefaultAzureCredential();
const client = new AttestationClient(endpoint, {credentials: credentials});

// Retrieve the set of attestation policy signers from the attestation client.
const attestationSigners = await client.getAttestationSigners();

如果不调用 attestTpm API,则无需提供凭据即可访问证明客户端。 这意味着,只需使用以下项即可创建客户端:

const client = new AttestationClient(endpoint);

// Retrieve the set of attestation policy signers from the attestation client.
const attestationSigners = await client.getAttestationSigners();

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

请注意,管理客户端 需要 Azure 凭据。

  const client = new AttestationAdministrationClient(endpoint, new DefaultAzureCredential());

  // Retrieve the SGX policy from the specified attestation instance.
  const policyResponse = await client.getPolicy(KnownAttestationType.SgxEnclave);

获取证明策略

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

const policyResult = await adminClient.getPolicy(attestationType);

// The text policy document is available in the `policyResult.body`
// property.

// The actual attestation token returned by the MAA service is available
// in `policyResult.token`.

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

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

如果服务实例在 AAD 模式下运行,则对 setPolicy 的调用将按预期方式进行:

const client = new AttestationAdministrationClient(endpoint, new DefaultAzureCredential());

const newPolicy = `<New Attestation Policy>`;

// Set the new attestation policy. Set the policy as an unsecured policy.
const setPolicyResult = await client.setPolicy(KnownAttestationType.SgxEnclave, newPolicy);

如果服务实例在独立模式下运行,则对 setPolicy 的调用要求客户端能够证明他们有权访问其中一个策略管理私钥和证书。

const client = new AttestationAdministrationClient(endpoint, new DefaultAzureCredential());

const newPolicy = `<New Policy Document>`;

// Set the new attestation policy. Set the policy as an secured policy.
const privateKey = <Retrieve isolated mode private key from storage>
const certificate = <Retrieve certificate associated with that private key>

const setPolicyResult = await client.setPolicy(
  KnownAttestationType.OpenEnclave,
  newPolicy,
  {
    privateKey: privateKey,
    certificate: certificate
  }
);

在封面下,setPolicy API 在策略文档certificate上创建包含的 JSON Web 令牌,并使用 privateKey 签名,然后发送到证明服务。

如果客户端希望确保在证明服务的 enclave 收到策略文档之前未修改证明策略文档,则可以使用 PolicyResult objct 中返回的属性,这些属性可用于验证服务是否收到了策略文档:

  • policySigner - 如果 setPolicy 调用包含 , certificate此值将是调用时 setPolicy 提供的证书。 如果未设置策略签名者,则此值将为 null。
  • policyTokenHash - 这是发送到 setPolicy API 服务的 JSON Web 签名 的哈希。

若要验证哈希,客户端可以创建证明策略令牌 (一个帮助程序类,该类表示用于设置证明策略) 的令牌,并验证从该令牌生成的哈希:

const expectedPolicy = createAttestationPolicyToken(
  `<Policy Document>`,
  privateKey,
  certificate);

// Use your favorite SHA256 hash generator function to create a hash of the
// stringized JWS.
const expectedHash = generateSha256Hash(expectedPolicy.serialize());

// The hash returned in expectedHash should match the value in
// `setResult.body.policyTokenHash`.

证明 SGX 和 Open Enclave

attestSgxEnclave使用 方法来证明 SGX enclave。

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

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

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

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

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

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

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

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

const attestationResult = await client.attestOpenEnclave(report, {
  runTimeData: binaryRuntimeData
});

发送到证明服务的 也可能 binaryRuntimeData 被解释为 JSON 数据。 在这种情况下,客户端应在证明 API 调用中指定 runTimeJson

const attestationResult = await client.attestOpenEnclave(report, {
  runTimeJson: binaryRuntimeData
});

同样,如果使用 Intel SDK 生成“报价单”,则可以使用以下方法来验证报价:

const attestationResult = await client.attestSgxEnclave(quote, {
  runTimeData: binaryRuntimeData
});

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

检索令牌证书

使用 getSigningCertificates 检索可用于验证从证明服务返回的令牌的证书。 请注意,此调用使用 Azure 凭据创建客户端,如果你调用 attestSgxEnclaveattestOpenEnclave API,则不需要该凭据

const credentials = new DefaultAzureCredential();
const client = new AttestationClient(endpoint, {credentials: credentials});

const attestationSigners = await client.getAttestationSigners();

console.log(`There are ${attestationSigners.length} signers`);

故障排除

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

try {
  await client.attestSgxEnclave(openEnclaveReport);
} catch (error) {
  console.log(`Exception thrown for invalid request: ${error.message}`);
}

日志记录

启用日志记录可能有助于发现有关故障的有用信息。 若要查看 HTTP 请求和响应的日志,请将 AZURE_LOG_LEVEL 环境变量设置为 info。 或者,可以在运行时通过调用 @azure/logger 中的 setLogLevel 来启用日志记录:

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

有关如何启用日志的更详细说明,请查看 @azure/logger 包文档

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

后续步骤

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

贡献

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

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

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

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

提供反馈

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

曝光数