Firma il tuo primo documento in 5 minuti

Una guida completa da un progetto VCL nuovo a un envelope XAdES firmato. Funziona da Delphi 7 a RAD Studio 13 e con C++Builder.

Delphi 7 – RAD Studio 13
C++ Builder
Profilo VeriFactu

Prima di iniziare

Servono solo due cose — sgcSign installato nell'IDE e un certificato PFX con cui firmare.

Cosa ti serve

  • sgcSign installato nel tuo IDE — consulta la pagina di download.
  • Un file di certificato PFX con la sua password (qualsiasi file X.509 PKCS#12 va bene).
  • Da Delphi 7 a RAD Studio 13, oppure qualsiasi versione di C++ Builder. Windows 32 bit e 64 bit sono entrambi supportati.
  • Nessuna dipendenza esterna — sgcSign utilizza Windows CNG/BCrypt per la crittografia e WinHTTP per le chiamate di rete.
make-test-cert.sh
# Non hai ancora un PFX? Genera un certificato di test autofirmato con OpenSSL:
openssl req -x509 -newkey rsa:2048 \
  -keyout key.pem -out cert.pem \
  -days 365 -nodes \
  -subj "/CN=sgcSign Test"

openssl pkcs12 -export \
  -inkey key.pem -in cert.pem \
  -out test.pfx \
  -password pass:secret

# Ora hai test.pfx con password "secret".

Crea un nuovo progetto

Avvia un'applicazione VCL Forms nel tuo IDE. Inserisci due memo e un pulsante sulla form — questa è l'intera UI.

Layout della form

  • memoXMLTMemo, incolla qui l'XML non firmato.
  • memoSignedTMemo, l'XML firmato appare qui dopo il clic sul pulsante.
  • btnSignTButton, collegato al gestore OnClick nel passo 2.
  • Nessun componente design-time richiesto — tutto viene creato nel codice.
Unit1.dfm
object Form1: TForm1
  Caption = 'Guida rapida sgcSign'
  ClientWidth  = 800
  ClientHeight = 600

  object memoXML: TMemo
    Left = 8
    Top  = 8
    Width  = 784
    Height = 240
  end

  object memoSigned: TMemo
    Left = 8
    Top  = 288
    Width  = 784
    Height = 300
  end

  object btnSign: TButton
    Left = 8
    Top  = 256
    Caption = 'Firma XML'
  end
end

Aggiungi il codice di firma

Carica un provider PFX, collegagli un document signer con il profilo VeriFactu e chiama SignXML.

Delphi

  • TsgcPFXKeyProvider importa il file .pfx tramite Windows CNG — la firma moderna SHA-256 funziona indipendentemente dal CSP originale.
  • TsgcDocumentSigner sceglie il livello XAdES corretto in base al profilo.
  • spVeriFactu seleziona VeriFactu dell'AEAT spagnola — XAdES-EPES, B-B, RSA-SHA256, C14N esclusiva.
  • Sostituisci la costante con uno qualsiasi dei 21 profili per paese — consulta Profili per paese.
Unit1.pas
procedure TForm1.btnSignClick(Sender: TObject);
var
  vKeyProvider: TsgcPFXKeyProvider;
  vSigner: TsgcDocumentSigner;
begin
  vKeyProvider := TsgcPFXKeyProvider.Create(nil);
  try
    vKeyProvider.FileName := 'certificate.pfx';
    vKeyProvider.Password := 'secret';
    vKeyProvider.LoadFromFile;

    vSigner := TsgcDocumentSigner.Create(nil);
    try
      vSigner.KeyProvider := vKeyProvider;
      vSigner.Profile := spVeriFactu;
      memoSigned.Text := vSigner.SignXML(memoXML.Text);
    finally
      vSigner.Free;
    end;
  finally
    vKeyProvider.Free;
  end;
end;

C++ Builder

  • Stessa struttura, stesse classi, stessi nomi di proprietà — il wrapper C++ è un porting 1:1 dell'API Delphi.
  • Il blocco __finally garantisce il rilascio dei provider anche se la firma genera un'eccezione.
  • UnicodeString è utilizzato end-to-end — nessuna conversione ANSI/UTF-8 di cui preoccuparsi.
Unit1.cpp
void __fastcall TForm1::btnSignClick(TObject *Sender)
{
  TsgcPFXKeyProvider *vKeyProvider = new TsgcPFXKeyProvider(NULL);
  try {
    vKeyProvider->FileName = "certificate.pfx";
    vKeyProvider->Password = "secret";
    vKeyProvider->LoadFromFile();

    TsgcDocumentSigner *vSigner = new TsgcDocumentSigner(NULL);
    try {
      vSigner->KeyProvider = vKeyProvider;
      vSigner->Profile = spVeriFactu;
      memoSigned->Text = vSigner->SignXML(memoXML->Text);
    } __finally {
      delete vSigner;
    }
  } __finally {
    delete vKeyProvider;
  }
}

Aggiungi le unit richieste

Due unit nella tua clausola uses — il provider PFX e il document signer.

Clausola uses Delphi

Ogni provider di chiavi vive nella sua unit, così paghi solo ciò a cui fai riferimento. sgcSign_DocumentSigner include il livello di routing che sceglie XAdES, PAdES o CAdES in base all'input.

Unit1.pas
uses
  Classes, SysUtils, Forms, StdCtrls, Controls,
  // sgc
  sgcSign_KeyProvider_PFX,
  sgcSign_DocumentSigner;

Include C++ Builder

Stesse unit, esposte come header .hpp. Il linker di C++ Builder risolve automaticamente le librerie statiche sottostanti.

Unit1.cpp
#include "sgcSign_KeyProvider_PFX.hpp"
#include "sgcSign_DocumentSigner.hpp"

Esegui e prova

Premi F9, incolla una fattura nel memo in alto, fai clic su Firma XML. L'envelope firmato appare nel memo in basso.

Compila ed esegui

Premi F9 nell'IDE. La form si apre con due memo e un pulsante. Nessuna eccezione, nessuna unit mancante.

Incolla l'input

Inserisci qualsiasi XML di fattura (o qualsiasi XML ben formato) in memoXML. Il signer lo normalizza internamente in UTF-8.

Verifica il risultato

memoSigned ora contiene il tuo XML con un elemento enveloped <ds:Signature> aggiunto. Salvalo, eseguilo con qualsiasi verificatore XAdES — oppure utilizza direttamente TsgcSignatureVerifier.

Unicode e l'overload WideString

Su Delphi 7, string è AnsiString. Usa gli overload WideString per preservare senza perdita caratteri polacchi, cirillici o greci.

Il problema

Su Delphi 7 l'overload string passa attraverso l'ACP del sistema. I caratteri diacritici in 'Jarosław' vengono preservati solo se l'ACP di sistema è CP1250. Se l'ACP è CP1252, i caratteri vengono corrotti nell'XML firmato.

Gli overload WideString bypassano completamente l'ACP — da UTF-16 a UTF-8 tramite WideCharToMultiByte con CP_UTF8. Su Delphi 2009+ entrambi gli overload sono equivalenti; UnicodeString è già UTF-16.

d7-unicode.pas
var
  Doc: IXMLDocument;       // MSXML6
  XML, Signed: WideString; // = MSXML6 DOMString
  Sign: TsgcXAdESSigner;
begin
  Doc.SaveToXML(XML);            // WideString in uscita, nessun passaggio ACP
  Signed := Sign.SignXML(XML);   // risolve all'overload WideString
  // I caratteri polacchi, cirillici e greci vengono preservati senza perdita
end;

UTC per impostazione predefinita

Tutti i timestamp X.509 / CRL / OCSP / TSA sono memorizzati come valori TDateTime in UTC, in linea con le specifiche ASN.1 sottostanti.

Visualizzazione in ora locale

Per le visualizzazioni all'utente finale, utilizza le proprietà *Local su ogni componente (ad es. vCert.NotAfterLocal) oppure converti manualmente con sgcUTCToLocal della unit sgcSign_Time.

Questo è in linea con RFC 5280 (X.509), RFC 3161 (TSA) e RFC 6960 (OCSP), che specificano tutti UTC. L'helper sgcUTCNow restituisce il TDateTime UTC corrente per il codice che deve confrontare timestamp.

time-zones.pas
uses sgcSign_Time;

// Mostra la validità del certificato in ora locale
Memo1.Lines.Add('Cert scade: ' +
                DateTimeToStr(vCert.NotAfterLocal));
Memo1.Lines.Add('Ora (UTC):    ' +
                DateTimeToStr(sgcUTCNow));

// Oppure converti manualmente
vLocal := sgcUTCToLocal(vCert.NotAfter);

Dove andare da qui

XAdES è solo l'inizio. PAdES, CAdES, profili, provider di chiavi e il server centralizzato sono a un clic di distanza.

Panoramica delle funzionalità

Scopri l'intera superficie API XAdES, PAdES, CAdES e l'infrastruttura di supporto per timestamp + OCSP.

Leggi di più →

21 profili per paese

VeriFactu, FatturaPA, KSeF, FACTUR-X, più 9 profili per contratti di lavoro UE. Cambio di giurisdizione in una sola riga.

Leggi di più →

10 provider di chiavi

PFX, PEM, archivio Windows, PKCS#11, Azure Trusted Signing, AWS KMS, Google KMS, Vault, Certum, CSC v2.

Leggi di più →

Server sgcSign

Centralizza la firma sull'intera build farm. API REST, admin web, GitHub Actions, Azure DevOps, Jenkins, Docker.

Leggi di più →

Pronto per la produzione?

Scarica la versione di prova, distribuisci un binario firmato oggi e acquista una licenza sgcSign quando sei soddisfatto.