使用 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 release 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.JARjsign.jar 的路径。
  • PATH_TO_CA.CERT:证书 ca.cert 的路径。
  • PATH_TO_ARTIFACT_TO_SIGN:要签名的工件的路径。

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