This guide provides instructions for creating a Cloud HSM key for Microsoft Authenticode signing through our CNG provider and SignTool.
You can find a Terraform-based blueprint version of this tutorial in the kms-solutions GitHub repository.
Use cases
The workflow outlined in this document helps address the following enterprise security needs:
- Sign firmware with a private key protected by a FIPS140-2 Level 3 HSM.
- Sign Windows artifacts using the Windows standard SignTool tool.
Before you begin
To complete this tutorial, you need the following:
- A Windows machine with the artifacts you want to sign.
- The latest Cloud KMS CNG provider release, which can be installed on your Windows machine using the included .msi installer.
Cloud Shell or your own Linux machine, to generate a certificate signing request or a certificate. On this machine, complete the configuration documented in OpenSSL Setup, to download and configure our PKCS#11 library.
Remember to run gcloud auth application-default login
if you haven't yet.
If you haven't already, download the latest Windows SDK on your Windows machine, which includes SignTool.
Configuration
Create a Cloud KMS-hosted signing key
Using Cloud Shell or your own machine, create a Cloud KMS key ring in your Google Cloud project using the following command:
gcloud kms keyrings create "KEY_RING" --location "LOCATION"
Then, create a Cloud KMS EC-P256-SHA256
hardware signing key in your
Google Cloud project, in the key ring that you have just created:
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"
Download the HSM attestation
An HSM attestation is proof that your key resides in an HSM. This proof may be required by your Certificate Authority (CA) to issue an Extended Validation (EV) certificate.
To download the HSM attestation associated with your Cloud KMS key, complete the following steps:
In the Google Cloud console, go to the Key Management page.
Select the key ring that contains the key you want to attest, and then select the key.
Click More more_vert for the key version you want to attest, and then click Verify attestation.
In the Verify attestation dialog, click Download attestation bundle. This downloads a zip file containing the attestation and certificate chains.
See Parsing the attestation for full instructions on how to verify the downloaded attestation.
Create a self-signed certificate with OpenSSL
This step is optional, but helps you familiarize yourself with subsequent steps before you go through the process and expense of purchasing a certificate signed by a Certificate Authority.
Using Cloud Shell or your own machine, generate a self-signed certificate with the Cloud KMS-hosted signing key. You can use OpenSSL to use a PKCS #11 URI instead of a file path and identify the key by its label. In the Cloud KMS PKCS #11 library, the key label is equivalent to the CryptoKey name.
openssl req -new -x509 -days 3650 -subj '/CN=test/' -sha256 -engine pkcs11 \
-keyform engine -key pkcs11:object=KEY_NAME > ca.cert
If this command fails, PKCS11_MODULE_PATH
may have been set incorrectly, or
you might not have the right permissions to use the Cloud KMS
signing key.
You should now have a certificate that looks like this:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
Copy the certificate to your Windows machine so that you can use it with SignTool to sign your artifacts.
Create a new certificate signing request
You can generate a certificate signing request (CSR) for a Cloud HSM signing key. Complete these steps if your certificate authority requires a CSR in order to generate a new certificate for code signing.
Using Cloud Shell or your own machine, run the following command:
openssl req -new -subj '/CN=CERTIFICATE_NAME/' DIGEST_FLAG \
-engine pkcs11 -keyform engine \
-key pkcs11:id=KEY_ID > REQUEST_NAME.csr
Replace the following:
CERTIFICATE_NAME
: a name for the certificate that you want to generate.DIGEST_FLAG
: a flag indicating the type of digest. Use-sha256
,-sha384
, or-sha512
depending on the algorithm of the key.KEY_ID
: the fully qualified resource ID of an asymmetric signing key version—for example,projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
.REQUEST_NAME
: a name for the certificate signing request.
Make sure you use the correct -sigopt
options for the type of key that you're
using.
You can't use an object ID longer than 100 characters with OpenSSL. Use short
KeyRing
and CryptoKey
names, or use pkcs11:object=KEY_NAME
instead.
For more information on the OpenSSL object ID limit, see the
related issue on GitHub.
Now that you have your CSR, you can provide it to your Certificate Authority (CA) to obtain the signing certificate. Use the certificate provided by your CA in the next section.
Sign an artifact with SignTool
Now that you have successfully created a certificate (either self-signed or obtained from the Certificate Authority) and copied it to your Windows machine, you can use it to sign a Windows artifact.
Use SignTool to sign the artifacts, using your Cloud KMS key and your certificate.
"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
Replace the following:
PATH_TO_SIGNTOOL.EXE
: the path tosigntool.exe
(eg.C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.19041.0\\x64\\signtool.exe
).PATH_TO_CA.CERT
: the path to your certificateca.cert
.PATH_TO_ARTIFACT_TO_SIGN
: the path to the artifact that you want to sign.
For a detailed explanation of each command option and supported artifact file formats, see the official SignTool documentation.