Firma de código utilizando Google Cloud KMS
Con Google Cloud KMS obtienes un HSM en la nube certificado por FIPS 140-2 Level 3. Puedes firmar código de manera segura, rápida y desde cualquier lugar. Además, los costos por cantidad de operaciones (firmas) son muy favorables. Cloud KMS admite la firma mediante Microsoft Cryptography API: Next Generation (CNG).
Para configurar y firmar código, es necesario realizar los siguientes pasos, que revisaremos paso a paso:
- Instalar el proveedor CNG
- Crear Key Ring y clave privada
- Crear CSR y obtener un certificado
- Firmar tu artefacto
Descarga el proveedor CNG y los paquetes necesarios
Google ha publicado su proveedor CNG en su repositorio en GitHub. Estos archivos se pueden instalar en tu sistema Windows mediante el archivo de instalación .msi adjunto. Este programa requiere configuración en forma de un archivo YAML que encontrarás en uno de los pasos de esta guía.
Ahora muévete a Linux (puedes usar WSL en Windows). Recomendamos crear la clave privada y el CSR en Linux; aunque en Windows puedes instalar OpenSSL en PowerShell, en Linux es menos probable que encuentres complicaciones. De hecho, el manual oficial de Google sigue este mismo procedimiento.
Para la comunicación con la nube utilizaremos la aplicación gcloud del paquete google-cloud-cli.
Crea un Key Ring y una clave privada en Cloud HSM
Los pasos siguientes deben realizarse en Linux. Crea un nuevo grupo de claves (Key Ring) para Cloud Key Management Service (KMS) API y dentro de él crea una clave privada, que está protegida por hardware mediante Cloud HSM. Selecciona el algoritmo RSA asimétrico para la firma y una longitud de clave de 3072 bits, porque SignTool no puede usar claves EC en combinación con Google Cloud KMS CNG.
Primero inicia sesión en Google en Linux y autoriza la sesión (esto también se aplica a Windows PowerShell):
gcloud auth application-default login
Así es como crearás un Key Ring para ubicar la clave privada:
gcloud kms keyrings create KEYRING-NAME \
--location=europe-west3 \
--project=PROJECT-NAME
Colocaremos la clave privada en este Key Ring. La generaremos también utilizando la utilidad gcloud; complete los nombres (en mayúsculas) según la realidad (nombre del proyecto en GCP) y tu denominación.
gcloud kms keys create KEY-NAME --keyring=KEYRING-NAME --location=europe-west3 --purpose=asymmetric-signing --protection-level=hsm --default-algorithm=rsa-sign-pkcs1-3072-sha256 --project=PROJECT-NAME
Una vez que hayas creado la primera versión de la clave, te recomendamos copiar Copiar nombre del recurso en su detalle en Cloud Console, ya que necesitarás esta información para el KEY_ID. Se ve así: projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1
Ahora volvamos a Windows, donde será necesario crear un archivo config.yaml con la configuración para la integración de KMS. En PowerShell ingresa lo siguiente:
$yaml = @"
resources:
- crypto_key_version: "projects/PROJECT-NAME/locations/europe-west3/keyRings/KEYRING-NAME/cryptoKeys/KEY-NAME/cryptoKeyVersions/1"
"@
$yaml = $yaml -replace "`t"," "
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText('C:\Windows\KMSCNG\config.yaml', $yaml, $utf8NoBom)
Creación de CSR
No es posible importar un certificado con clave privada a HSM, ni exportar este par. Por lo tanto, la clave privada y el CSR deben originarse en HSM; luego el CSR se entrega a SSLmarket y se firma por DigiCert. La importación del certificado emitido es en el siguiente paso.
Es mejor crear el CSR en Linux, usando la biblioteca libengine-pkcs11-openssl, libkmsp11 y API. Por supuesto, también necesitarás el paquete google-cloud-cli.
Así es como se ve la creación del CSR (después de pkcs11:object= completa el nombre de la clave (CryptoKey) según GCP):
openssl req -new \
-subj "/C=CZ/O=ZONER /CN=ZONER" \
-sha256 -engine pkcs11 -keyform engine \
-key "pkcs11:object=KEY_NAME;type=private" \
-reqexts v3_req -config <(cat /etc/ssl/openssl.cnf; printf "\n[v3_req]\nextendedKeyUsage=codeSigning\n") \
-out cs-request.csr
La solicitud para DigiCert la tendrás en el archivo cs-request.csr en la carpeta donde estés trabajando. Envíanos este CSR.
Obtención del certificado
Haz que DigiCert firme el CSR creado y recibirás un nuevo certificado de firma de código. No necesitas insertarlo en Google Cloud Console, solo es necesario tener la clave privada. Trabajaremos localmente con el certificado en Windows, guárdalo en un lugar accesible del disco.
Firma tus artefactos
Continuamos en Windows. A partir de 2024, Google lanzó el Cloud KMS CNG Provider oficial, que se registra en Windows como Crypto Service Provider (CSP) / Key Storage Provider (KSP) bajo el nombre de Google Cloud KMS Provider. Esto permite que SignTool use la(s) clave(s) en la nube y no solo localmente en el token.
Firmaremos utilizando SignTool del SDK de Windows y la versión x64 de la herramienta; recomendamos la última versión. Asegúrate de ingresar los parámetros correctos (ver explicación debajo del ejemplo).
Ejemplo de firma usando SignTool y PowerShell:
& $SignTool sign `
/v /debug `
/fd sha256 /td sha256 `
/tr http://timestamp.digicert.com `
/f "PATH_TO_CERT" `
/csp "Google Cloud KMS Provider" `
/kc "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1" `
"PATH_TO_FILE_TO_SIGN"
Explicación:
- /f PATH_TO_CERT es la ruta al archivo con el certificado de firma de código (parte pública). Lo recibirás fusionado de esta manera desde nosotros si solicitas su emisión para HSM.
- /csp especifica el proveedor CNG particular, ya que puede haber varios en Windows. Google Cloud KMS Provider está registrado como, por ejemplo, “Microsoft Software Key Storage Provider”.
- /kc (Key Container) es la ruta a la clave específica y su versión (KMS CryptoKeyVersion), correspondiente al KEY_ID mencionado anteriormente.
Durante la firma verás qué certificado se seleccionó para la firma y el resultado. Dado que SignTool tiene problemas para vincular el certificado a la clave privada en la nube (a través de CSP/KSP), recomiendo tener el certificado guardado localmente en un archivo. La selección por el nombre de la organización o hash SHA1 del certificado es problemática y generalmente no funciona; solo funcionó el certificado en un archivo.
The following certificate was selected:
Issued to: ZONER a.s.
Issued by: DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1
Expires: Wed Nov 12 01:59:59 2025
SHA1 hash: F9BC96AC1764AD9F2072780FFB64940538A3B292
The following additional certificates will be attached:
Issued to: DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1
Issued by: DigiCert Trusted Root G4
Expires: Tue Apr 29 01:59:59 2036
SHA1 hash: 7B0F360B775F76C94A12CA48445AA2D2A875701C
Done Adding Additional Store
Successfully signed: C:\Users\jindrich.zechmeister\HelloSign.exe
Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0
Bonus - verificación de la firma
Podemos verificar la firma digital recién creada usando SignTool.
PS C:\Users\jindrich.zechmeister> signtool verify /pa c:\Users\jindrich.zechmeister\App.exe
File: c:\Users\jindrich.zechmeister\App.exe
Index Algorithm Timestamp
========================================
0 sha256 RFC3161
Successfully verified: c:\Users\jindrich.zechmeister\App.exe
¡El archivo EXE firmado ha sido exitosamente firmado!
Fuentes:
- artículo Puedes firmar artefactos de Microsoft Windows con claves protegidas por Cloud HSM, disponible en Blog de Google Cloud.
- GCP Docs: Proveedor para Microsoft Cryptography API: Next Generation (CNG)
- GCP Docs: Uso del Proveedor CNG y SignTool para firmar artefactos de Windows
Lo sentimos que no haya encontrado lo necesario aquí.
Ayúdanos mejorar el artículo, por favor. Escríbenos lo que esperaba aquí y no encontró.