sgcSign en cinco minutos

Dos componentes firman un documento: un firmante y un proveedor de claves. Esta página firma un PDF con PAdES, usando un certificado del almacén de certificados de Windows, y después muestra cómo verificar lo que has producido. Si prefieres firmar XML, más abajo hay un recorrido más largo de XAdES.

PAdES, XAdES, CAdES, ASiC
Diez proveedores de claves, de PFX a HSM en la nube
Windows, Win32 y Win64

Un firmante y un proveedor de claves

El firmante conoce el formato del documento. El proveedor de claves sabe dónde vive la clave privada. Se encuentran en una sola propiedad.

El firmante

TsgcPAdESSigner, declarado en sgcSign_PAdES.pas y registrado en la página SGC Sign de la paleta. SignPDFFile recibe una ruta de entrada y una ruta de salida.

El proveedor de claves

TsgcWindowsCertStoreProvider para el almacén de certificados de Windows, o TsgcPFXKeyProvider para un archivo .pfx. Ambos están en la misma página de la paleta.

La propiedad que los une

KeyProvider, cuyo tipo es la interfaz IsgcKeyProvider y no una referencia a un componente. Esa distinción importa para el tiempo de vida, y la sección de problemas de más abajo explica por qué.

Plataforma

Win32, Win64, Linux64, macOS en Intel y Apple Silicon, iOS y Android. En Windows el hashing y la firma pasan por la API CNG de Windows, en cualquier otra plataforma por la criptografía en Pascal puro de la propia biblioteca, sin OpenSSL que desplegar. El proveedor del almacén de certificados de Windows es el único componente que sigue siendo solo para Windows.

Requisitos y ediciones

sgcSign no tiene niveles de características, así que esta tabla trata de compiladores y plataformas y no de ediciones.

Qué Valor
IDE Delphi 7 hasta RAD Studio 13, y C++Builder. La ruta de C++Builder pone la carpeta lib en la ruta System Include en lugar de en la ruta de biblioteca.
Cláusula uses La demo escribe sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes, sgcSign_PAdES, sgcSign_KeyProvider_WinCertStore, sgcSign_KeyProvider_PEM, sgcSign_KeyProvider_PFX. Quita los proveedores que no uses.
Ediciones No hay ninguna. El sgcVer.inc propio del producto no contiene ningún define SGC_EDT_*, y ninguna característica está controlada por nivel. Una biblioteca, todos los componentes, en todas las licencias. Los niveles comerciales dependen del número de puestos: single, team y site, además de una Community Edition gratuita.
Plataforma, comprobada en el código fuente Win32, Win64, Linux64, OSX64, OSXARM64, iOS y Android. La criptografía pasa por una unit de enlace, sgcSign_Crypto.pas, que es CNG en Windows y Pascal puro en todo lo demás, HTTP es WinHTTP en Windows y el cliente de la RTL de Delphi en el resto, y los paquetes de runtime habilitan Linux64 y macOS en Intel desde Delphi 10.3, Android e iOS desde la 10.4, y macOS en Apple Silicon desde la 11. sgcSign_KeyProvider_WinCertStore.pas es la única unit que es solo para Windows.
Dependencias externas Ninguna. En Windows la biblioteca llama directamente a las APIs CNG y WinHTTP de Windows, y en las demás plataformas usa su propia criptografía en Pascal puro y el cliente HTTP de la RTL de Delphi, así que no hay DLL de OpenSSL que desplegar con tu aplicación.
Valores por defecto Un TsgcPAdESSigner recién creado ya tiene un perfil utilizable: el constructor establece el perfil PAdES básico, el nivel de firma baseline B y SHA-256. No tienes que tocar Profile para producir una firma válida.

¿Prefieres XML a PDF? El recorrido de XAdES en cinco minutos firma un documento XML con un archivo PFX, y cubre el problema de Unicode en Delphi 7 y la hora de firma en UTC. Esta página es la contrapartida con PDF y almacén de certificados.

Instala y localiza la página de la paleta

Compila el paquete de runtime antes de instalar el de tiempo de diseño, porque el segundo hace referencia al primero.

1. Descomprime

Descomprime la descarga en una carpeta, llamada {$DIR} más abajo.

2. Ruta de biblioteca

Tools, Environment Options, Directories. Añade {$DIR}\delphi\source, que se aplica a todas las versiones de RAD Studio.

3. Añade la carpeta lib

Añade también la carpeta específica de la versión, por ejemplo {$DIR}\delphi\libD13\$(Platform) en RAD Studio 13, hasta libD7 en Delphi 7. Para C++Builder se ponen en la ruta System Include.

4. Compila los paquetes

Abre Packages\sgcSignD13.groupproj para tu versión de IDE, o sgcSignC13.groupproj para C++Builder. Compila primero el paquete sgcSign y después instala el dclsgcSign.

5. Comprueba la paleta

Aparece una página llamada SGC Sign, con los firmantes, el verificador, los clientes de sellado de tiempo y OCSP, y los diez proveedores de claves. En Windows incluye además el firmante y el verificador de Authenticode.

Firma un PDF, en unas veinte líneas

Elige un certificado, crea el firmante, apúntalo al proveedor y llama a SignPDFFile. La primera pestaña usa el almacén de certificados de Windows y la segunda un archivo PFX.

frmMain.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes,
  sgcSign_PAdES, sgcSign_KeyProvider_WinCertStore;

procedure TFormMain.btnSignClick(Sender: TObject);
var
  vSigner: TsgcPAdESSigner;
  vKeyProvider: TsgcWindowsCertStoreProvider;
  vProviderIntf: IsgcKeyProvider;
  vOutputFile: string;
begin
  vKeyProvider := TsgcWindowsCertStoreProvider.Create(nil);
  vSigner := TsgcPAdESSigner.Create(nil);
  try
    vKeyProvider.SelectCertificateBySubject('My Company');
    Log('Certificate found: ' + vKeyProvider.Certificate.Subject);

    // Hold the interface in an explicit local: an inline "as" cast
    // would leave a compiler-generated interface temporary alive in
    // this stack frame until the routine returns, i.e. past
    // vKeyProvider.Free, and releasing it would touch freed memory.
    vProviderIntf := vKeyProvider as IsgcKeyProvider;
    vSigner.KeyProvider := vProviderIntf;
    vSigner.Reason := 'Demo signature';
    vSigner.Location := 'Spain';
    vSigner.SignerName := 'sgcSign Demo';

    vOutputFile := ChangeFileExt(edInputFile.Text, '_signed.pdf');
    vSigner.SignPDFFile(edInputFile.Text, vOutputFile);

    Log('SUCCESS: PDF signed with PAdES profile');
    Log('Output file: ' + vOutputFile);
  finally
    vSigner.Free;
    vProviderIntf := nil;
    vKeyProvider.Free;
  end;
end;

Fíjate en lo que no está aquí. Profile nunca se toca, porque el constructor ya establece un perfil PAdES básico, el nivel de firma baseline B y SHA-256. El comentario sobre el temporal de la interfaz es de la propia demo incluida, y el orden de liberación en el bloque finally es la razón por la que importa.

frmMain.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes,
  sgcSign_PAdES, sgcSign_KeyProvider_PFX;

var
  vSigner: TsgcPAdESSigner;
  vKeyProvider: TsgcPFXKeyProvider;
  vProviderIntf: IsgcKeyProvider;
begin
  vKeyProvider := TsgcPFXKeyProvider.Create(nil);
  vSigner := TsgcPAdESSigner.Create(nil);
  try
    vKeyProvider.FileName := 'C:\certs\signer.pfx';
    vKeyProvider.Password := GetPfxPassword;
    vKeyProvider.LoadFromFile;
    Log('Certificate loaded (PFX): ' + vKeyProvider.Certificate.Subject);

    vProviderIntf := vKeyProvider as IsgcKeyProvider;
    vSigner.KeyProvider := vProviderIntf;

    vSigner.SignPDFFile('C:\docs\contract.pdf',
      'C:\docs\contract_signed.pdf');
  finally
    vSigner.Free;
    vProviderIntf := nil;
    vKeyProvider.Free;
  end;
end;

La única diferencia con la primera pestaña es qué proveedor creas y cómo lo apuntas a una clave. Todo desde KeyProvider := en adelante es idéntico, y eso vale para los diez proveedores, incluido el hardware PKCS#11 y los servicios de claves en la nube.

uVerify.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Verifier;

var
  oVerifier: TsgcSignatureVerifier;
  vVerifier: IsgcSignatureVerifier;
  oStream: TFileStream;
begin
  oVerifier := TsgcSignatureVerifier.Create(nil);
  oStream := TFileStream.Create('C:\docs\contract_signed.pdf',
    fmOpenRead or fmShareDenyWrite);
  try
    // VerifyPDF is reached through the interface the component implements
    vVerifier := oVerifier as IsgcSignatureVerifier;

    if vVerifier.VerifyPDF(oStream) = vsValid then
      Writeln('valid')
    else
      Writeln(oVerifier.GetVerificationDetails);
  finally
    vVerifier := nil;
    oStream.Free;
    oVerifier.Free;
  end;
end;

La misma regla de interfaz que con el firmante: asigna la conversión a una variable local con nombre y límpiala antes de liberar el componente. GetValidationReportXML produce un informe en el formato de informe de validación de ETSI cuando un booleano no es evidencia suficiente.

Las dos primeras pestañas proceden de la demo incluida Demos\Delphi\PAdES\frmMain.pas, con sus ramas reducidas a un solo camino por pestaña. El comentario sobre mantener la interfaz en una variable local con nombre es de la propia demo, y merece la pena conservarlo. Una demo hermana más completa, Demos\Delphi\PAdES_Providers, hace lo mismo con proveedores de hardware y de nube.

Comprueba la firma, no te limites a mirar el archivo

Ha aparecido un archivo. Eso no es lo mismo que una firma que valida.

El certificado se resolvió

Lee Certificate.Subject después de seleccionar, como hace la demo. Es la diferencia entre firmar con el certificado que querías y firmar con el primero que coincidió. IsLoaded responde a la misma pregunta como booleano.

El archivo apareció

SignPDFFile escribe la ruta de salida que le diste. La demo incluida la deriva con ChangeFileExt para que el archivo firmado quede junto al original.

Lanza una excepción, no devuelve un código

No hay un resultado que comprobar, así que pon la llamada en un try except y lee el mensaje de la excepción. Es lo que hace la demo, y es el único canal de fallo.

La firma valida

Un archivo no es una firma válida. TsgcSignatureVerifier.VerifyPDF devuelve un TsgcVerificationStatus que comparas con vsValid, y GetVerificationDetails explica un fallo. Abrir el archivo en un lector de PDF le muestra lo mismo a una persona.

Lo que suele fallar la primera vez

Seis problemas explican casi todas las primeras firmas.

Una access violation al salir

Este es el que la demo advierte en su propio comentario. KeyProvider recibe un IsgcKeyProvider, así que una conversión as en línea deja viva una referencia de interfaz generada por el compilador hasta que la rutina retorna, que es después de haber liberado el componente proveedor. Asigna la interfaz a una variable local con nombre y libera en este orden: el firmante, luego la interfaz a nil y después el proveedor.

Profile no es una cadena

Es un objeto TsgcSignProfileConfig. Defines Profile.Profile y Profile.SignatureLevel, no Profile := 'something'. El constructor ya rellena un valor por defecto utilizable, así que el primer ejemplo no necesita tocarlo en absoluto.

No se encuentra ningún certificado

SelectCertificateBySubject busca por el asunto, y SelectCertificateByThumbprint por la huella. Lee Certificate.Subject después de seleccionar, como hace la demo, para ver qué certificado obtuviste realmente. EnumerateCertificates lista lo que hay disponible.

No compila fuera de Windows

No puede. El firmante y cada proveedor ponen Windows en la cláusula uses de la interfaz sin condicional, así que es un error de compilación y no una unit vacía. sgcSign es una biblioteca de Windows.

La firma aparece como desconocida en el lector

Una firma básica no lleva ancla de confianza ni datos de revocación. Añade un sello de tiempo mediante TSAClient y pasa a un perfil de larga duración cuando el documento tenga que seguir siendo verificable después de que caduque el certificado.

SignPDFFile lanza una excepción en lugar de devolver un código

Es el diseño. No hay un valor de retorno que comprobar, así que pon la llamada en un try except y lee el mensaje de la excepción, que es lo que hace la demo incluida.

Más allá de la primera firma

Cuatro direcciones, todas dentro de la misma biblioteca.

Otros formatos de documento

XAdES y XMLDSig para XML, CAdES para CMS separado, contenedores ASiC, y firmantes dedicados para paquetes ClickOnce, NuGet y VSIX. En Windows hay también un firmante Authenticode.

Todos los componentes de sgcSign

Dónde vive la clave

Se incluyen diez proveedores de claves: PFX, PEM, el almacén de Windows, hardware PKCS#11, Azure Trusted Signing, AWS KMS, Google Cloud KMS, Certum SimplySign, HashiCorp Vault y el protocolo de firma remota CSC.

Proveedores de claves

Perfiles por país

Veintiún perfiles por país y sector, desde el VeriFactu español hasta los formatos de facturación de la UE, cada uno con los campos y el nivel de firma que espera ese régimen.

Perfiles de firma

Firma en otro sitio

sgcSign Server es un demonio autoalojado que guarda las claves y firma bajo petición, de modo que el certificado nunca sale de la máquina en la que confías.

sgcSign Server

Referencia, demos y documentación

Los proyectos de demo se incluyen dentro de la descarga, en Demos\Delphi. La demo de PAdES es la que sirve de base a esta página.

Recorrido de XAdES en cinco minutos El inicio rápido en versión larga: un proyecto VCL nuevo, un archivo PFX y un sobre XML firmado.
Proveedores de claves Los diez lugares donde puede vivir una clave privada, y lo que necesita cada uno.
Perfiles de firma Los veintiún perfiles por país y sector, y lo que requiere cada uno.
Tutorial de firma de PDF Un recorrido más largo de PAdES, incluidas las firmas visibles.
sgcSign Server El demonio de firma autoalojado, para cuando la clave no debe viajar.
Descarga la versión de prueba El mismo instalador que en producción, con límite de tiempo, más una Community Edition gratuita.

Lecturas relacionadas: la introducción a sgcSign y el servidor de firma de código. Cada producto tiene su propio inicio rápido, listado en la página de primeros pasos.

Preguntas sobre el inicio rápido de sgcSign

TsgcPAdESSigner, declarado en sgcSign_PAdES.pas, y un proveedor de claves. Para el almacén de certificados de Windows es TsgcWindowsCertStoreProvider, de sgcSign_KeyProvider_WinCertStore.pas. Para un archivo .pfx es TsgcPFXKeyProvider, de sgcSign_KeyProvider_PFX.pas. Ambos están en la página SGC Sign de la paleta. Asigna el proveedor a la propiedad KeyProvider del firmante y llama a SignPDFFile(aInputFile, aOutputFile).
Porque KeyProvider está tipado como la interfaz IsgcKeyProvider, no como un componente. Una conversión as en línea crea un temporal de interfaz generado por el compilador que sigue vivo en el marco de pila hasta que la rutina retorna, que es después de haber liberado el componente proveedor, y liberarlo entonces toca memoria que ya no existe. La demo asigna la conversión a una variable local con nombre y luego libera en este orden: el firmante, la interfaz a nil, el proveedor. Copia ese orden.
No hay ediciones. El sgcVer.inc del producto no contiene ningún define SGC_EDT_*, y ningún componente ni formato está controlado por nivel. Cada licencia contiene todos los firmantes, todos los proveedores de claves y todos los perfiles por país. Los niveles comerciales son números de puestos, single, team y site, y hay una Community Edition gratuita junto a la versión de prueba.
Sí, desde la 2026.10.0. La biblioteca compila y funciona en Linux64, en macOS para Intel y Apple Silicon, en iOS y en Android, además de Win32 y Win64. Allí funcionan la firma y verificación de documentos, la lectura y escritura de archivos PKCS#12, la firma de archivos PE, catálogos, MSI, MSP, MSIX y APPX, y los tokens PKCS#11, y el servidor de firma se ejecuta como demonio de systemd en Linux. Dos proveedores usan el almacén de claves que ya tiene la plataforma, el llavero de Apple y el Android KeyStore. Dos cosas siguen siendo de Windows: el proveedor del almacén de certificados de Windows, y los formatos específicos de Windows en el servidor y en la herramienta de línea de comandos, que aún los rechazan en una compilación que no sea de Windows aunque la propia biblioteca los firma.
No para una primera firma. El constructor ya establece un perfil PAdES básico, el nivel de firma baseline B y SHA-256. Cuando sí quieras cambiarlo, Profile es un objeto TsgcSignProfileConfig, así que defines Profile.Profile y Profile.SignatureLevel en lugar de asignar una cadena. Para una firma de larga duración pasa al perfil LTV y al nivel baseline LT, y asocia un TSAClient.
Usa TsgcSignatureVerifier. VerifyPDF recibe un stream y devuelve un TsgcVerificationStatus, que comparas con vsValid. GetVerificationDetails explica un fallo, y GetValidationReportXML produce un informe en el formato de informe de validación de ETSI cuando necesitas evidencia y no un booleano.
No. En Windows sgcSign calcula hashes y firma mediante las APIs CNG y BCrypt y habla con la red mediante WinHTTP. En Linux, macOS, iOS y Android usa su propia criptografía en Pascal puro y el cliente HTTP de la RTL de Delphi. En ambos casos no hay DLL de OpenSSL que distribuir, que es una de las razones por las que el despliegue es sencillo.
Cubren trabajos distintos a propósito. El inicio rápido de cinco minutos construye un proyecto VCL nuevo, usa un archivo PFX y firma un documento XML con XAdES, y entra en el problema de Unicode en Delphi 7 y en la hora de firma en UTC. Esta página firma un PDF con PAdES usando un certificado del almacén de Windows, que es lo que hace la demo de PAdES incluida. Lee primero esta y después esa cuando necesites XML.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para firmar tu primer documento?

Descarga la versión de prueba, o empieza con la Community Edition gratuita.