Saltar al contenido principal

CI/CD y herramientas de compilación

El servicio de firma de código remota de sslTrus puede integrarse en flujos de CI/CD, compilación de aplicaciones y creación de paquetes de instalación, firmando automáticamente los artefactos de publicación después de la compilación o el empaquetado.

Los escenarios de integración típicos actualmente admitidos incluyen:

  • GitHub Actions
  • Electron Builder
  • Advanced Installer

Según las capacidades de la herramienta de compilación, puede usar directamente la GitHub Action de sslTrus, invocar la CLI de SignTool o completar la integración a través de la interfaz de firma personalizada proporcionada por la herramienta de compilación.

GitHub Actions

sslTrus proporciona una GitHub Action oficial:

ssltrus-official/code-sign-action

Puedes firmar el código de forma remota directamente en el flujo de trabajo de GitHub Actions sobre los artefactos de compilación.

La acción invocará el servicio de firma de código remota de sslTrus para completar la firma y actualizará directamente los archivos especificados, compatible con runners de Linux, macOS y Windows.

Preparar los secretos de GitHub

Se recomienda guardar las credenciales de firma de código remota en los secretos de GitHub Actions:

SSLTRUS_ACCESS_KEY
SSLTRUS_ACCESS_SECRET
SSLTRUS_CERT_CODE

No escribas el Access Secret directamente en el archivo Workflow.

Configuración básica

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: build/app.exe

Después de una firma exitosa, build/app.exe será reemplazado directamente por el archivo firmado.

Firmar múltiples archivos

files admite configurar múltiples archivos mediante múltiples líneas:

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
build/installer.msi

También puede utilizar rutas de archivo separadas por comas.

Las rutas de archivo duplicadas solo se procesarán una vez.

Configuración completa

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
build/installer.msi
dry-run: false
timestamp-rfc3161: http://timestamp.acs.microsoft.com
description: Example Application
description-url: https://example.com

Parámetros principales:

ParámetroObligatorioValor predeterminadoDescripción
access-key-Clave de acceso de sslTrus
access-secret-Secreto de acceso de sslTrus
cert-code-Número de certificado de firma de código
files-Ruta del archivo que se debe firmar
nicsrsNofalseSi se debe utilizar el servicio NICSRS
dry-runNofalseEjecutar una firma de prueba con un certificado de prueba local
timestamp-rfc3161NoautoServidor de sellado de tiempo RFC 3161
descriptionNo-Descripción del programa escrita en la firma Authenticode
description-urlNo-URL del programa escrita en la firma Authenticode

Ejemplo de Workflow completo

A continuación se muestra un ejemplo de compilación, firma y carga del artefacto de compilación en un Runner de Windows:

name: Build and Sign

on:
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: windows-latest

steps:
- name: Check out repository
uses: actions/checkout@v7

- name: Build
run: |
# 在这里执行实际构建命令

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
timestamp-rfc3161: http://timestamp.acs.microsoft.com

- name: Upload signed files
uses: actions/upload-artifact@v7
with:
name: signed-files
path: |
build/app.exe
build/library.dll

Se recomienda colocar el paso de firma en:

Compilar → Empaquetar → Firma de código → Publicar

Antes del paso de publicación en el flujo de trabajo.

Runner multiplataforma

GitHub Action se puede invocar en diferentes Runners:

strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest

runs-on: ${{ matrix.os }}

Por lo tanto, aunque la tarea de compilación se ejecute en Linux o macOS, puede usar la misma Action para completar la firma remota de los archivos compatibles.

Dry Run

Si necesita verificar el Workflow y la lógica de procesamiento de archivos, puede habilitar:

dry-run: true

Este modo utiliza certificados de prueba locales y no invoca el servicio remoto de firma de código.

Por ejemplo:

- name: Test signing
uses: ssltrus-official/code-sign-action@v1
with:
access-key: dummy
access-secret: dummy
cert-code: dummy
files: build/app.exe
dry-run: true

dry-run aún modificará el archivo de destino, así que no lo interpretes como un modo de vista previa que no modifica archivos en absoluto.

Electron Builder

Electron Builder puede invocar la CLI sslTrus SignTool mediante una función de firma personalizada, completando automáticamente la firma de archivos ejecutables e instaladores de Windows durante el proceso de compilación de la aplicación Electron.

Flujo típico:

Electron Builder

customSign

SignTool CLI

sslTrus 远程代码签名服务

云端 HSM

Requisitos previos

Antes de comenzar, necesitará:

  • Disponer de un servicio de firma de código remoto de sslTrus.
  • Haber obtenido la Access Key y el Access Secret.
  • Haber obtenido el número de certificado de firma de código.
  • El proyecto Electron se compila con electron-builder.
  • El entorno de compilación puede ejecutar la CLI de sslTrus SignTool, que puede descargarse desde la página de lanzamiento del cliente de sslTrus.

Configurar credenciales

Puede pasar las credenciales al script de compilación mediante variables de entorno:

Linux y macOS:

export SIGNTOOL_ACCESS_KEY="YOUR_ACCESS_KEY"
export SIGNTOOL_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SIGNTOOL_CERT_CODE="YOUR_CERT_CODE"

Windows PowerShell:

$env:SIGNTOOL_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SIGNTOOL_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SIGNTOOL_CERT_CODE = "YOUR_CERT_CODE"

Estas variables son leídas por el script de firma personalizado de Electron y luego se pasan a la CLI de SignTool.

Configurar Electron Builder

En:

electron-builder.mjs

O en el archivo de configuración de Electron Builder que el proyecto realmente utiliza, configure una función de firma personalizada para Windows:

export default {
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
},
],
sign: customSign,
signingHashAlgorithms: ['sha256'],
},
};

Entre ellos, win.sign es el punto de entrada de firma personalizado proporcionado oficialmente por Electron Builder. Para más detalles, consulte la documentación de firma de código de Windows de Electron Builder.

customSign

Responsable de llamar a la CLI de sslTrus SignTool.

Función de firma personalizada

Ejemplo:

import { execFileSync } from 'node:child_process';

async function customSign(configuration) {
const {
SIGNTOOL_ACCESS_KEY,
SIGNTOOL_ACCESS_SECRET,
SIGNTOOL_CERT_CODE,
} = process.env;

if (
!SIGNTOOL_ACCESS_KEY ||
!SIGNTOOL_ACCESS_SECRET ||
!SIGNTOOL_CERT_CODE
) {
throw new Error('Missing sslTrus signing credentials');
}

execFileSync(
'./signtool',
[
'sign',
'--access-key',
SIGNTOOL_ACCESS_KEY,
'--access-secret',
SIGNTOOL_ACCESS_SECRET,
'--cert-code',
SIGNTOOL_CERT_CODE,
'--file',
configuration.path,
'--override=true',
'--sha1=false',
'--sha2=true',
'--timestamp-rfc3161=http://timestamp.acs.microsoft.com',
],
{
stdio: 'inherit',
},
);
}

Se recomienda usar una matriz de parámetros para invocar el subproceso, en lugar de concatenar un comando de shell completo, a fin de reducir los problemas de escape de rutas y manejo de caracteres especiales.

Electron Builder llamará la función de firma una vez por cada algoritmo hash indicado en signingHashAlgorithms. El ejemplo anterior solo habilita SHA-256, por lo que se llama una vez por archivo.

Ejecutar la compilación

Una vez completada la configuración, ejecute Electron Builder con normalidad:

npx electron-builder build \
--config electron-builder.mjs \
--win \
--x64

Electron Builder llamará automáticamente a customSign cuando necesite firmar archivos.

Una compilación de Electron puede firmar varios archivos, por ejemplo:

MyApp.exe
helper.dll
update.exe
uninstall.exe
MyApp Setup.exe

Por lo tanto, no debe entenderse simplemente como “un empaquetado de Electron produce solo una firma”.

La cantidad real de veces que se firma depende de cuántos archivos realizan la firma remota durante el proceso de compilación.

Advanced Installer

Advanced Installer es una herramienta de creación de paquetes de instalación basada en la tecnología Windows Installer.

Puede usar la función de herramienta de firma personalizada de Advanced Installer para llamar a sslTrus SignTool CLI, de modo que los productos de compilación como MSI, EXE y CAB completen automáticamente la firma de código remota durante el proceso de empaquetado.

Requisitos previos

Debe preparar:

Configurar la herramienta de firma personalizada

Abra lo siguiente del proyecto de Advanced Installer:

Digital Signature

Página de configuración.

Después de habilitar la firma de código, seleccione la herramienta de firma como:

Custom

Establezca la ruta de la herramienta de firma en el ejecutable de sslTrus SignTool CLI.

Por ejemplo:

C:\Tools\sslTrus\signtool.exe

Los parámetros personalizados requieren la llamada a:

sign

Subcomando, y pase al cliente:

  • Access Key
  • Access Secret
  • Cert Code
  • Configuración de firma SHA-2
  • Servidor de sello de tiempo
  • Ruta del archivo

Se recomienda proporcionar el Access Key y el Access Secret prioritariamente a través de medios seguros, evitando guardar el Access Secret válido a largo plazo en texto plano en archivos de proyecto de acceso público.

Ejemplo de parámetros de SignTool

La lógica de firma correspondiente es similar a:

signtool.exe sign ^
--access-key="YOUR_ACCESS_KEY" ^
--access-secret="YOUR_ACCESS_SECRET" ^
--cert-code="YOUR_CERT_CODE" ^
--nest=true ^
--sha1=false ^
--sha2=true ^
--timestamp-rfc3161=http://timestamp.acs.microsoft.com ^
--desc="Example Application" ^
--override=true ^
--file "app.exe"

En Advanced Installer, la ruta real del archivo debe ser pasada por su mecanismo de herramienta de firma personalizada; no la fije como el ejemplo app.exe.

Configuración de compilación

Si utiliza Advanced Installer para firmar automáticamente los archivos internos del paquete de instalación, debe verificar simultáneamente los métodos de compilación y compresión.

Según la configuración real del proyecto, algunos métodos de archivo CAB pueden afectar el flujo de firma personalizada; debe confirmar que los archivos que finalmente necesitan ser firmados puedan ser invocados en la etapa correspondiente.

Después de completar la configuración, puede verificarlo en la página de firma digital de Advanced Installer:

Files configured for signing

Así se confirma qué archivos se firmarán durante el proceso de compilación.

Número de firmas

Advanced Installer puede firmar varios archivos por separado durante la compilación de un solo paquete de instalación.

Por ejemplo:

ArchivoFirma
app.exe1 vez
helper.dll1 vez
uninstall.exe1 vez
installer.msi1 vez
Total4 veces

Por lo tanto:

一次构建 ≠ 一次签名

Debe calcularse en función del número real de archivos o acciones de firma remota completadas.

Número de firmas

Las herramientas de CI/CD y de compilación suelen procesar automáticamente múltiples artefactos, por lo que el número de firmas requiere una atención especial.

Principios básicos:

签名次数 = 实际成功完成的签名动作数量

Por ejemplo:

app.exe        → 1 次
library.dll → 1 次
installer.msi → 1 次

Si los tres archivos se firman correctamente:

合计 = 3 次

Las herramientas de compilación como Electron Builder y Advanced Installer también pueden generar y firmar automáticamente:

  • El programa principal.
  • DLL.
  • El actualizador.
  • El desinstalador.
  • MSI.
  • El paquete de instalación EXE.
  • Otros archivos ejecutables auxiliares.

Por lo tanto, la cantidad de firmas debe confirmarse según los registros de compilación y los artefactos firmados reales, en lugar de estimarse según la cantidad de ejecuciones del Pipeline o del Build.

Para conocer más reglas, consulte Referencias.

Sello de tiempo

Generalmente se recomienda agregar un sello de tiempo confiable al software lanzado oficialmente.

Las integraciones de GitHub Actions, Electron Builder y Advanced Installer pueden utilizar sellos de tiempo RFC 3161, por ejemplo:

http://timestamp.acs.microsoft.com

La marca de tiempo no constituye una nueva operación de firma de código y no incrementa por separado el número de firmas de código.

Para conocer el soporte de protocolos y las restricciones de uso de las diferentes TSA, consulte Materiales de referencia.

Seguridad de credenciales

En entornos automatizados, se debe prestar especial protección a:

Access Key
Access Secret
Cert Code

Entre ellos, el Access Secret debe gestionarse como un Secreto y no debe:

  • Subirse a un repositorio Git.
  • Escribirse en texto plano en un Workflow público.
  • Imprimirse en los registros de compilación.
  • Escribirse en una imagen Docker pública.
  • Transmitirse a sistemas de compilación de terceros de manera insegura.

GitHub Actions recomienda usar:

GitHub Actions Secrets

Otros sistemas de CI/CD deberían utilizar sus propios mecanismos de gestión de Secret, Credential o Variable.

Cómo elegir

EscenarioMétodo recomendado
Flujo de trabajo de GitHub ActionsGitHub Actions
Compilación de aplicaciones ElectronElectron Builder
Creación de instaladores MSI / EXEAdvanced Installer
Automatización con Shell / PowerShell ordinarioSignTool CLI
Software de Windows con soporte nativo de KSPWindows Provider
Desarrollo propio del flujo de firmaIntegración por API

Si el sistema de compilación puede invocar directamente programas de línea de comandos, se puede utilizar SignTool CLI; si la herramienta ya proporciona la interfaz estándar de Windows KSP/CSP, se dará prioridad al método de integración correspondiente con Windows Provider.