使用 Jsign 和 PKCS#11 为 Windows 工件签名

本指南介绍了如何通过 PKCS#11 和 Jsign 创建 Cloud HSM 密钥,以用于 Microsoft Authenticode 签名。

使用场景

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

  • 使用受 FIPS140-2 3 级 HSM 保护的私钥对固件进行签名。
  • 无需使用 signtool 即可对 Windows 制品进行签名。

准备工作

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

  • 包含您要签名的制品的 Windows 机器。确保此机器上已安装 Java。
  • Cloud Shell 或您自己的 Linux 机器,以生成证书签名请求或证书。在此机器上,完成 OpenSSL 设置中记录的配置。

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

在 Windows 设备上,使用以下 PowerShell 命令下载最新的 Jsign 版本 JAR 文件:

wget https://github.com/ebourg/jsign/releases/download/JSIGN.VERSION/jsign-JSIGN.VERSION.jar -O jsign.jar

配置

创建 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 机器,以便您可以使用该证书通过 Jsign 对制品进行签名。

创建新的证书签名请求

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

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

使用 Jsign 对制品进行签名

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

如需查看支持的文件格式列表,请运行 jsign --help 命令。

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

java -jar PATH_TO_JSIGN.JAR --storetype GOOGLECLOUD \
  --storepass $(gcloud auth application-default print-access-token) \
  --keystore projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING \
  --alias KEY_NAME \
  --certfile PATH_TO_CA.CERT
  PATH_TO_ARTIFACT_TO_SIGN

替换以下内容:

  • PATH_TO_JSIGN.JAR:jsign.jar 的路径。
  • PATH_TO_CA.CERT:证书 ca.cert 的路径。
  • PATH_TO_ARTIFACT_TO_SIGN:要签名的工件的路径。

如需详细了解每个命令选项,请参阅官方 Jsign 文档。