This guide provides instructions for creating a Cloud HSM key for Microsoft Authenticode signing through PKCS#11 and Jsign.
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 without having to use signtool.
Before you begin
To complete this tutorial, you need the following:
- A Windows machine with the artifacts you want to sign. Make sure that Java is installed on this machine.
Remember to run
gcloud auth application-default login if you haven't yet.
On your Windows machine, download the latest Jsign release JAR file using the following powershell command:
wget https://github.com/ebourg/jsign/releases/download/JSIGN.VERSION/jsign-JSIGN.VERSION.jar -O jsign.jar
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
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 Jsign 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
-sha512depending on the algorithm of the key.
KEY_ID: the fully qualified resource ID of an asymmetric signing key version—for example,
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
Sign an artifact with Jsign
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.
For a list of supported file formats, run the
jsign --help command.
Use Jsign to sign the artifacts, using your Cloud KMS key and your certificate.
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
Replace the following:
PATH_TO_JSIGN.JAR: the path to
PATH_TO_CA.CERT: the path to your certificate
PATH_TO_ARTIFACT_TO_SIGN: the path to the artifact that you want to sign.
For a detailed explanation of each command option, see the official Jsign documentation.