Azure 托管 HSM TLS 卸载库

Azure 托管 HSM 提供了 TLS 卸载库,该库符合 2.40 版 PKCS#11 规范。 Azure 托管 HSM 并非支持 PKCS#11 规范中列出的所有函数;相反,TLS 卸载库仅支持一组有限的用于通过 F5 (BigIP) 和 Nginx 实现 SSL/TLS 卸载的机制和接口函数,主要用于在 TLS 握手期间生成 TLS 服务器证书密钥和数字签名。

有关详细信息,请参阅 Azure 托管 HSM TLS 卸载库 GitHub

TLS 卸载库将在内部使用 Azure 密钥保管库 REST API 与 Azure 托管 HSM 进行交互。

入门

PKCS#11 属性

若要与 PKCS#11 正确集成,生成密钥(通过 C_GenerateKeyPair)和确定密钥对象的位置(通过 C_FindObjectsInit/C_FindObjects)时需要一个可在 Azure 密钥保管库密钥对象上存储 PKCS#11 属性的解决方案。 TLS 卸载库会将这些必要的 PKCS#11 属性转换为 Azure 密钥保管库标记。

这些“属性标记”具有特殊前缀:

  • p11_pri_{P11 属性名称} - 私钥属性
  • p11_pub_{P11 属性名称} - 公钥属性

TLS 卸载库将正确设置 Azure 密钥保管库密钥操作和密钥生存期属性,以便服务可以对生成的密钥正确实施这些限制。 这些属性也会像其他 PKCS#11 属性一样存储为标记,以支持查询功能。

使用 TLS 卸载库的应用程序将使用一个或多个 PKCS#11 属性来定位和使用密钥对象。

警告

TLS 卸载库生成的密钥及其标记可通过 Azure 密钥保管库 REST API 进行访问。 使用 Azure 密钥保管库 REST API 操控这些 P11 属性标记可能会破坏 TLS 卸载库应用程序。

密钥生成

TLS 卸载库包括 mhsm_p11_create_key 这一密钥创建工具。 在不带任何命令行参数的情况下运行该工具时,系统会显示该工具的正确用法。

该密钥创建工具需要一个服务主体,该服务主体将在“/keys”范围内分配给“托管 HSM 加密用户”角色。

该密钥创建工具将从环境变量 MHSM_CLIENT_ID 和 MHSM_CLIENT_SECRET 读取服务主体凭据:

  • MHSM_CLIENT_ID - 必须设置为服务主体的应用程序(客户端)ID
  • MHSM_CLIENT_SECRET - 必须设置为服务主体的密码(客户端密码)

对于托管标识,不需要上述环境变量。

  • 使用 --identity 参数通过 mhsm_p11_create_key 工具启用托管标识。
  • 应在 MHSM 配置文件 (mhsm-pkcs11.conf) 中引用用户分配的托管标识的 client_id。 如果未提供用户分配的托管标识的 client_id,它会将其视为系统分配的托管标识。

该密钥创建工具将在创建密钥时随机为其生成名称。 为方便起见,系统会将完整的 Azure 密钥保管库密钥 ID 和密钥名称打印到控制台。

MHSM_CLIENT_ID="<service-principal-application-id>" \
MHSM_CLIENT_SECRET="<service-principal-password>" \
mhsm_p11_create_key --RSA 4K --label tlsKey

Key is generated successfully. \
Managed HSM Key ID: https://myhsm.managedhsm.chinacloudapi.cn/keys/p11-6a2155dc40c94367a0f97ab452dc216f/92f8aa2f1e2f4dc1be334c09a2639908 \
Key Name: p11-6a2155dc40c94367a0f97ab452dc216f

该密钥创建工具的 --label 参数将为生成的私钥和公钥指定所需的 CKA_LABEL。 这些属性通常是配置支持的 TLS 卸载解决方案时的必需属性(例如 nginx SSL 配置设置“ssl_certificate_key”)。

在通过 Azure CLI 更改角色分配,需要提供密钥名称。

访问控制

TLS 卸载库会将 C_FindObjectsInit 转换为 Azure 密钥保管库 REST API 调用,该调用将在 /keys 范围内运行。 MHSM 服务需要 TLS 卸载库用户在此范围内具有读取权限,以便授权执行通过密钥创建工具创建的密钥的查找操作。

有关 Azure 托管 HSM 本地 RBAC 的详细信息,请参阅:

以下部分介绍了为 TLS 卸载库服务主体和托管标识实现访问控制的不同方法。

TLS 卸载服务主体

TLS 卸载服务主体由使用 TLS 卸载库访问密钥的应用程序使用,且应通过角色分配至少获得以下权限:

  • 对托管 HSM 中所有密钥的 KeyRead 权限
  • 对 TLS 卸载所需的密钥的 KeySign 权限

管理员用户

管理员用户将创建自定义角色定义和角色分配。 因此,应在“/”范围内为管理员用户分配以下内置角色之一:

  • 托管 HSM 加密管理人员
  • 托管 HSM 策略管理员
  • 托管 HSM 管理员

密钥生成服务主体

密钥生成服务主体与密钥创建工具 (mhsm_p11_create_key) 一起用于生成 TLS 卸载密钥。 对于此服务主体,应在“/keys”范围内为其分配“托管 HSM 加密用户”角色。

Azure CLI

Azure CLI 可用于执行角色分配等任务。

宽松方法

宽松方法更简单,适合在 Azure 托管 HSM 专门于 TLS 卸载时使用。

请在“/keys”范围内为 TLS 卸载服务主体分配“加密用户”角色。 这可为 TLS 卸载服务主体提供生成并查找密钥的权限,以便其完成 TLS 卸载。

az keyvault role assignment create --hsm-name ContosoMHSM \
--role "Managed HSM Crypto User"  \
--assignee TLSOffloadServicePrincipal@contoso.com  \
--scope /keys

对于托管标识,指定命令参数,如下所示:

az keyvault role assignment create --hsm-name ContosoMHSM \
      --role "Managed HSM Crypto User"  \
       --assignee-object-id <object_id>  \
       --assignee-principal-type MSI \
       --scope /keys

精细方法

精细方法将实现精细的访问控制。 它需要两个服务主体(TLS 卸载服务主体和密钥生成服务主体),以及一个管理员用户。

目的是限制 TLS 卸载服务主体的权限,以支持 TLS 卸载所需的最低权限。 用户必须具有其他密钥的读取权限,以支持卸载库中的 C_FindObject* 函数。

TLS 卸载库用户读取角色

实现精细方法的第一步是创建自定义角色。 此操作仅需执行一次。

具有托管 HSM 加密官、托管 HSM 管理员或托管 HSM 策略管理员角色的管理员用户将创建自定义的“TLS 库用户读取角色”角色定义:

az keyvault role definition create --hsm-name ContosoMHSM --role-definition '{ \
"roleName": "TLS Library User Read Role", \
"description": "Grant Read access to keys", \
"actions": [], \
"notActions": [], \
"dataActions": ["Microsoft.KeyVault/managedHsm/keys/read/action"], \
"notDataActions": [] \
}'

生成密钥

可以使用密钥生成服务主体和密钥创建工具 (mhsm_p11_create_key) 来生成密钥。

授予权限

管理员用户将为 TLS 卸载服务主体分配以下角色。

  • 在“/keys”范围内分配“TLS 库用户读取角色”
  • 在“/keys/{密钥名称}”范围内分配“托管 HSM 加密用户”角色

在以下示例中,密钥名称为“p11-6a2155dc40c94367a0f97ab452dc216f”。

az keyvault role assignment create --hsm-name ContosoMHSM  \
--role "TLS Library User Read Role"  \
--assignee TLSOffloadServicePrincipal@contoso.com  \
--scope /keys

az keyvault role assignment create --hsm-name ContosoMHSM  \
--role "Managed HSM Crypto User"  \
--assignee TLSOffloadServicePrincipal@contoso.com  \
--scope /keys/p11-6a2155dc40c94367a0f97ab452dc216f

连接缓存

为了提高对托管 HSM 服务的签名调用的性能,TLS 卸载库将其 TLS 连接缓存到托管 HSM 服务服务器。 默认情况下,TLS 卸载库最多缓存 20 个 TLS 连接。 可以通过 MHSM 配置文件 (mhsm-pkcs11.conf) 控制连接缓存。

"ConnectionCache": {
        "Disable": false, 
        "MaxConnections": 20
}

Disable

如果此值为 true,则将禁用连接缓存。 它默认为启用状态。

MaxConnections

指定缓存的最大连接数。 最大连接限制应根据应用程序使用的并发 PKCS11 会话数进行配置。 应用程序通常会创建 PKCS11 会话池,并使用它们从线程池并行生成签名请求。 MaxConnections 应与应用程序生成的并发签名请求数匹配。

每秒签名请求数 (RPS) 取决于并发请求数和缓存的连接数。 如果并发 PKCS11 签名请求数低于此限制,则指定更高的数字甚至默认限制不会提高签名 RPS。 实现标准 B1 HSM 池突发模式的最大并发连接数约为 30,具体取决于实例类型。 但应尝试使用不同的数值来找出最佳的并发连接数。

请参阅应用程序文档或联系应用程序供应商,详细了解应用程序如何使用 PKCS11 库。

使用 TLS 卸载库

生成密钥

TLS 卸载库包括 mhsm_p11_create_key 这一密钥创建工具。 在不带任何命令行参数的情况下运行该工具时,系统会显示该工具的正确用法。

该密钥创建工具需要一个服务主体,该服务主体将在“/keys”范围内分配给“托管 HSM 加密用户”角色。

该密钥创建工具将从环境变量 MHSM_CLIENT_ID 和 MHSM_CLIENT_SECRET 读取服务主体凭据。

  • MHSM_CLIENT_ID - 必须设置为服务主体的应用程序(客户端)ID
  • MHSM_CLIENT_SECRET - 必须设置为服务主体的密码(客户端密码)

该密钥创建工具将在创建密钥时随机为其生成名称。 为方便起见,系统会将完整的 Azure 密钥保管库密钥 ID 和密钥名称打印到控制台。

MHSM_CLIENT_ID="<service-principal-application-id>" \
MHSM_CLIENT_SECRET="<service-principal-password>" \
mhsm_p11_create_key --RSA 4K --label tlsKey

Key is generated successfully.
Managed HSM Key ID: https://myhsm.managedhsm.chinacloudapi.cn/keys/p11-6a2155dc40c94367a0f97ab452dc216f/92f8aa2f1e2f4dc1be334c09a2639908 \
Key Name: p11-6a2155dc40c94367a0f97ab452dc216f

该密钥创建工具的 --label 参数将为生成的私钥和公钥指定所需的 CKA_LABEL。 这些属性通常是配置支持的 TLS 卸载解决方案时的必需属性(例如 nginx SSL 配置设置“ssl_certificate_key”)。

如果计划实现对密钥的精细访问,则需要密钥名称。

实现无密钥 TLS

生成密钥并使用密钥来实现无密钥 TLS 的方法有两种:一种是较简单、较宽松的方法,另一种则是较精细的方法;后者可提供更出色的安全性。 这些方法在实现工作量和安全强制实施方面存在差异。

较简单的方法

  1. 为 TLS 卸载库创建服务主体(例如 TLSOffload ServicePrincipal)
  2. 在“/keys”范围内为 TLS 卸载服务主体分配“托管 HSM 加密用户”角色。
    az keyvault role assignment create --hsm-name ContosoMHSM \
    --role "Managed HSM Crypto User"  \
    --assignee TLSOffloadServicePrincipal@contoso.com  \
    --scope /keys
    
  3. 按照如何使用 TLS 卸载库生成密钥中的步骤生成具有所需标签的密钥。
  4. 将 TLS 服务器配置为使用托管 HSM TLS 卸载库作为 PKCS#11 接口库
  5. 使用密钥标签和 TLS 卸载服务主体凭据配置 TLS 服务器(例如,nginx SSL 配置设置“ssl_certificate_key”)

精细方法

  1. 创建具有以下角色的管理员用户(例如 TLSOffloadAdminUser):
    • “/”范围内的“托管 HSM 加密官”角色
  2. 为 TLS 卸载密钥生成创建密钥生成服务主体(例如 TLSOffloadKeyGenServicePrincipal),并分配以下角色:
    • “/keys”范围内的“托管 HSM 加密用户”角色。
  3. 为 TLS 卸载创建服务主体(例如 TLSOffload ServicePrincipal)
  4. 管理员用户创建以下自定义角色定义:
    az keyvault role definition create --hsm-name ContosoMHSM --role-definition '{ \
    "roleName": "TLS Library User Read Role", \
    "description": "Grant Read access to keys", \ 
    "actions": [], \
    "notActions": [], \
    "dataActions": ["Microsoft.KeyVault/managedHsm/keys/read/action"], \
    "notDataActions": []
    }'
    
  5. 按照《如何使用 TLS 卸载库生成密钥》中的说明生成具有所需标签的密钥。 生成密钥时,请使用密钥生成服务主体(例如,TLSOffloadKeyGenServicePrincipal)。 记下密钥标签和密钥名称。 例如:
    • 密钥标签:tlsKey
    • 密钥名称:p11-6a2155dc40c94367a0f97ab452dc216f
  6. 管理员用户将以下角色分配给 TLS 卸载服务主体
    • “/keys”范围内的“TLS 库用户读取角色”
    • “/keys/{密钥名称}”范围内的“托管 HSM 加密用户”角色
    az keyvault role assignment create --hsm-name ContosoMHSM  \
    --role " TLS Library User Read Role"  \
    --assignee TLSOffloadServicePrincipal @contoso.com  \
    --scope /keys
    
    az keyvault role assignment create --hsm-name ContosoMHSM  \
    --role "Managed HSM Crypto User"  \
    --assignee TLSOffloadServicePrincipal@contoso.com  \
    --scope /keys/p11-6a2155dc40c94367a0f97ab452dc216f
    
  7. 将 TLS 服务器配置为使用 Azure 托管 HSM TLS 卸载库作为 PKCS#11 接口库
  8. 使用密钥标签和 TLS 卸载服务主体凭据配置 TLS 服务器(例如,nginx SSL 配置设置“ssl_certificate_key”)

后续步骤