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

本指南介绍了如何通过我们的 CNG 提供程序和 SignTool 创建 Cloud HSM 密钥,以便进行 Microsoft Authenticode 签名。

您可以在 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 选项。

您无法在 OpenSSL 中使用长度超过 100 个字符的对象 ID。使用短 KeyRingCryptoKey 名称,或改用 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.EXEsigntool.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 文档