使用 CNG 提供程序和 SignTool 为 Windows 工件签名

本指南介绍了如何通过 CNG 提供程序和 SignTool 创建用于 Microsoft Authenticode 签名的 Cloud HSM 密钥。

您可以在 kms-solutions GitHub 代码库中找到本教程的基于 Terraform 的蓝图版本。

使用场景

本文档中概述的工作流程有助于满足以下企业安全需求:

  • 使用受 FIPS140-2 3 级 HSM 保护的私钥对固件进行签名。
  • 使用 Windows 标准 SignTool 工具对 Windows 制品进行签名。

准备工作

如需完成本教程,您需要满足以下条件:

  • 包含您要签名的制品的 Windows 机器。
  • 最新的 Cloud KMS CNG 提供程序版本,可以使用随附的 .msi 安装程序将其安装在 Windows 机器上。
  • Cloud Shell 或您自己的 Linux 机器,以生成证书签名请求或证书。在此机器上,完成 OpenSSL 设置中记录的配置,以下载和配置我们的 PKCS#11 库。

如果您尚未运行 gcloud auth application-default login,请务必运行。

在 Windows 计算机上下载最新的 Windows SDK(如果尚未下载),其中包含 SignTool。

配置

创建 Cloud KMS 托管的签名密钥

使用 Cloud Shell 或您自己的机器,在您的 Google Cloud 项目中使用以下命令创建 Cloud KMS 密钥环:

gcloud kms keyrings create "KEY_RING" --location "LOCATION"

然后,在Google Cloud 项目中,在您刚刚创建的密钥环中创建 Cloud KMS EC-P256-SHA256 硬件签名密钥:

gcloud kms keys create "KEY_NAME" --keyring "KEY_RING" \
  --project "PROJECT_ID" --location "LOCATION" \
  --purpose "asymmetric-signing" --default-algorithm "ec-sign-p256-sha256" \
  --protection-level "hsm"

下载 HSM 证明

HSM 证明用于证明您的密钥位于 HSM 中。您的证书授权机构 (CA) 可能需要此证明才能颁发扩展验证 (EV) 证书。

如需下载与 Cloud KMS 密钥关联的 HSM 证明,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往密钥管理页面。

    前往 Key Management

  2. 选择包含您要证明的密钥的密钥环,然后选择密钥。

  3. 对于要证明的密钥版本,点击更多 ,然后点击验证证明。

  4. 在验证证明对话框中,点击下载证明软件包。 这会下载包含证明和证书链的 zip 文件。

如需查看有关如何验证下载的证明的完整说明,请参阅解析证明。

使用 OpenSSL 创建自签名证书

此步骤是可选步骤,但有助于您在购买由证书授权机构签名的证书之前,先熟悉后续步骤,以免在购买过程中遇到问题。

使用 Cloud Shell 或您自己的机器,通过 Cloud KMS 托管的签名密钥生成自签名证书。您可以使用 OpenSSL 来使用 PKCS #11 URI(而非文件路径),并通过标签来标识密钥。在 Cloud KMS PKCS #11 库中,密钥标签等同于 CryptoKey 名称。

openssl req -new -x509 -days 3650 -subj '/CN=test/' -sha256 -engine pkcs11 \
  -keyform engine -key pkcs11:object=KEY_NAME > ca.cert

如果此命令失败,则 PKCS11_MODULE_PATH 可能设置不正确,或者您可能没有使用 Cloud KMS 签名密钥的适当权限。

您现在应该有一个如下所示的证书:

-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----

将证书复制到 Windows 计算机,以便您可以使用 SignTool 对制品进行签名。

创建新的证书签名请求

您可以为 Cloud HSM 签名密钥生成证书签名请求 (CSR)。如果您的证书授权机构需要 CSR 来生成新的证书以进行代码签名,请完成以下步骤。

使用 Cloud Shell 或您自己的机器运行以下命令:

openssl req -new -subj '/CN=CERTIFICATE_NAME/' DIGEST_FLAG \
  -engine pkcs11 -keyform engine \
  -key pkcs11:id=KEY_ID > REQUEST_NAME.csr

替换以下内容:

  • CERTIFICATE_NAME:您要生成的证书的名称。
  • DIGEST_FLAG:一个标志,用于指明摘要的类型。请使用 -sha256、-sha384 或 -sha512,具体取决于密钥的算法。
  • KEY_ID:非对称签名密钥版本的完全限定资源 ID,例如 projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1。
  • REQUEST_NAME:证书签名请求的名称。

请确保您为所使用的密钥类型使用了正确的 -sigopt 选项。

您无法使用长度超过 100 个字符的对象 ID 与 OpenSSL 搭配使用。请使用简短的 KeyRing 和 CryptoKey 名称,或改用 pkcs11:object=KEY_NAME。 如需详细了解 OpenSSL 对象 ID 限制,请参阅 GitHub 上的相关问题。

现在,您已拥有 CSR,可以将其提供给证书授权机构 (CA) 以获取签名证书。在下一部分中使用 CA 提供的证书。

使用 SignTool 为制品签名

现在,您已成功创建证书(自签名或从证书授权机构获取)并将其复制到 Windows 计算机,接下来您可以使用该证书对 Windows 制品进行签名。

使用 SignTool 和您的 Cloud KMS 密钥及证书对制品进行签名。

"PATH_TO_SIGNTOOL.EXE" sign ^
  /v /debug /fd sha256 /t http://timestamp.digicert.com ^
  /f PATH_TO_CA.CERT ^
  /csp "Google Cloud KMS Provider" ^
  /kc projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1 ^
  PATH_TO_ARTIFACT_TO_SIGN

替换以下内容:

  • PATH_TO_SIGNTOOL.EXE:signtool.exe 的路径(例如,C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.19041.0\\x64\\signtool.exe)。
  • PATH_TO_CA.CERT:证书 ca.cert 的路径。
  • PATH_TO_ARTIFACT_TO_SIGN:要签名的工件的路径。

如需详细了解每个命令选项和支持的制品文件格式,请参阅官方 SignTool 文档。