A solo un mese dal lancio iniziale, sgcSign 2026.5 introduce un'importante espansione della libreria. La versione aggiunge la firma Microsoft Authenticode per i binari Windows, tre nuovi firmatari per la distribuzione del codice (ClickOnce, NuGet, VSIX), un pacchetto completo di conformità eIDAS UE (contenitori ASiC, trust list LOTL / EUTL, firma remota Cloud Signature Consortium), nove profili nazionali per il lavoro preconfigurati, un profilo Peppol BIS Billing 3.0 bulgaro, un generatore nativo di QR Code, il supporto ECDSA P-256/384/521 e RSA-PSS, integrazioni CI/CD complete, e un ampio insieme di correzioni di conformità XAdES / PFX.
Questo articolo illustra i punti salienti, con snippet Delphi pronti da incollare per ogni nuovo componente.
Microsoft Authenticode
TsgcAuthenticodeSigner firma i file Windows Portable Executable (.exe, .dll, .sys) secondo la specifica Authenticode. Il firmatario analizza il PE, ne calcola l'hash con l'algoritmo Authenticode (saltando il checksum e la tabella dei certificati esistente), costruisce un blob PKCS#7 SignedData completo con il contenuto SPC indirect data, e lo aggiunge alla tabella dei certificati del binario.
Sono supportati gli hash da SHA-1 a SHA-512, i timestamp RFC 3161 vengono incorporati come attributi non firmati, e AppendSignature := True produce firme annidate (ad esempio doppia firma SHA-1 + SHA-256 per la compatibilità con le versioni legacy di Windows).
uses
sgcSign_Authenticode, sgcSign_KeyProvider_PFX, sgcSign_TSAClient;
var
oSigner: TsgcAuthenticodeSigner;
oPFX: TsgcPFXKeyProvider;
oTSA: TsgcTSAClient;
begin
oPFX := TsgcPFXKeyProvider.Create(nil);
oPFX.FileName := 'codesign.pfx';
oPFX.Password := 'secret';
oTSA := TsgcTSAClient.Create(nil);
oTSA.URL := 'http://timestamp.digicert.com';
oSigner := TsgcAuthenticodeSigner.Create(nil);
try
oSigner.KeyProvider := oPFX;
oSigner.TSAClient := oTSA;
oSigner.Hash := ahSHA256; // ahSHA1 / ahSHA256 / ahSHA384 / ahSHA512
oSigner.Level := alT; // alBES or alT (with timestamp)
oSigner.Description := 'My Application';
oSigner.URL := 'https://www.example.com';
oSigner.SignFile('MyApp.exe', 'MyApp-signed.exe');
finally
oSigner.Free; oTSA.Free; oPFX.Free;
end;
end;
La verifica è simmetrica. TsgcAuthenticodeVerifier.Verify restituisce un record con il risultato, gli hash calcolati e incorporati, il soggetto/emittente del firmatario, e l'indicazione se è presente un timestamp:
var
oVer: TsgcAuthenticodeVerifier;
oRes: TsgcAuthenticodeVerifyResult;
begin
oVer := TsgcAuthenticodeVerifier.Create(nil);
try
oRes := oVer.Verify('MyApp-signed.exe');
if oRes.Valid then
ShowMessage('Signed by ' + oRes.SubjectName)
else
ShowMessage('Invalid: ' + oRes.ErrorMessage);
finally
oVer.Free;
end;
end;
Firma Authenticode basata solo sull'hash
Per gli artefatti CI di grandi dimensioni (installer, runtime, driver) il caricamento dell'intero PE su un firmatario remoto risulta oneroso. Il nuovo flusso di firma basato solo sull'hash consente al client di calcolare localmente l'hash Authenticode e di inviare al sgcSign Server solo il digest di 32 byte. Il server restituisce il blob PKCS#7 non attaccato, e il client lo incorpora nuovamente nel binario, riducendo i caricamenti di più megabyte a pochi KB su agenti con larghezza di banda limitata.
// Local: compute the hash with sgcSign_PE_Hasher, POST it to the server,
// receive the SignedData blob, then append it to the PE's certificate table.
var
oSigner: TsgcAuthenticodeSigner;
vHash, vPKCS7: TBytes;
begin
// vHash := ComputePEHash('MyApp.exe', haSHA256);
vPKCS7 := oSigner.SignHash(vHash, ahSHA256);
// EmbedPKCS7IntoPE('MyApp.exe', vPKCS7, 'MyApp-signed.exe');
end;
La stessa operazione è esposta dall'endpoint POST /api/v1/sign/authenticode/hash del server, dal flag CLI sgcsign sign --prehash, e dal metodo TsgcSignClient.SignAuthenticodeHashAsync sull'SDK .NET.
Firmatari ClickOnce, NuGet e VSIX
Tre nuovi firmatari coprono l'ecosistema di distribuzione per sviluppatori Microsoft.
TsgcClickOnceSigner firma i manifest di distribuzione .application e i manifest applicativi .exe.manifest utilizzando XML-DSig W3C enveloped, riproducendo l'output di mage.exe di Microsoft. Il firmatario riscrive il nodo publisherIdentity con l'issuerKeyHash del certificato.
uses sgcSign_ClickOnce;
var oCO: TsgcClickOnceSigner;
begin
oCO := TsgcClickOnceSigner.Create(nil);
try
oCO.KeyProvider := oPFX;
oCO.Hash := haSHA256;
oCO.PublisherName := 'My Company';
oCO.SignManifestFile('MyApp.application', 'MyApp-signed.application');
finally
oCO.Free;
end;
end;
TsgcNuGetSigner firma i pacchetti author .nupkg, producendo un blob CMS/PKCS#7 SignedData (certificato di firma v2, tipo di impegno "proof of origin") con una controfirma RFC 3161 opzionale.
uses sgcSign_NuGet;
var oNu: TsgcNuGetSigner;
begin
oNu := TsgcNuGetSigner.Create(nil);
try
oNu.KeyProvider := oPFX;
oNu.TSAClient := oTSA;
oNu.Hash := haSHA256;
oNu.SignPackageFile('MyLib.1.0.0.nupkg', 'MyLib.1.0.0.signed.nupkg');
finally
oNu.Free;
end;
end;
TsgcVSIXSigner implementa le firme digitali OPC (Open Packaging Convention) per le estensioni di Visual Studio, calcolando i riferimenti XML-DSig per ciascuna parte e riscrivendo [Content_Types].xml e il _rels/.rels del pacchetto.
uses sgcSign_VSIX;
var oVX: TsgcVSIXSigner;
begin
oVX := TsgcVSIXSigner.Create(nil);
try
oVX.KeyProvider := oPFX;
oVX.Hash := haSHA256;
oVX.SignPackageFile('MyExt.vsix', 'MyExt-signed.vsix');
finally
oVX.Free;
end;
end;
Tutti e tre riutilizzano la stessa interfaccia IsgcKeyProvider dei firmatari XAdES / PAdES / CAdES esistenti, quindi un token AWS KMS, Azure Trusted Signing o PKCS#11 configurato per la firma di fatture può essere riutilizzato per la firma di binari senza alcuna configurazione aggiuntiva.
Pacchetto eIDAS UE / conformità
Questa versione introduce il pacchetto eIDAS, tre nuove unit che, insieme, permettono a un'applicazione Delphi di validare una firma rispetto al framework di fiducia ufficiale dell'UE e di produrre contenitori per l'archiviazione a lungo termine.
Contenitori ASiC (ETSI EN 319 162-1)
sgcSign_ASiC costruisce e analizza contenitori ASiC-S (documento singolo) e ASiC-E (documenti multipli) in entrambe le varianti XAdES e CAdES. L'output è uno ZIP deterministico con la voce mimetype per prima e la firma collocata sotto META-INF/.
uses sgcSign_ASiC;
var
oDocs: TsgcASiCDocumentArray;
vBytes: TBytes;
begin
SetLength(oDocs, 1);
oDocs[0].Name := 'invoice.xml';
oDocs[0].Data := TFile.ReadAllBytes('invoice.xml');
// aSignatureXML comes from TsgcXAdESSigner (detached signature over the doc)
vBytes := TsgcASiCContainer.BuildXAdES(apASiCE, oDocs, vXAdESSignature);
TFile.WriteAllBytes('invoice.asice', vBytes);
end;
Trust list LOTL / EUTL
sgcSign_TrustList scarica la EU List of Trusted Lists, segue i puntatori alla trust list di ciascuno Stato membro, e analizza ogni voce TSPService. Il risultato è un catalogo in memoria di ~3.600 servizi distribuiti su 31 Stati membri. La ricerca IsQualifiedAtTime classifica qualsiasi certificato come "emesso da un TSP qualificato" a un determinato momento di firma, l'operazione necessaria per elevare una firma da avanzata (AdES) a qualificata (QES) ai sensi dell'articolo 25 del regolamento eIDAS.
Cloud Signature Consortium (CSC v2)
TsgcCSCKeyProvider è un'implementazione di IsgcKeyProvider per l'API Cloud Signature Consortium v2, lo standard europeo per la firma qualificata remota utilizzato da Buypass, Certinomis, Globalsign EU, InfoCert, Namirial, Trust Pro e altri QTSP. Il provider gestisce l'autenticazione Basic / OAuth2 / OTP, elenca le credenziali dell'utente, recupera la catena dei certificati ed esegue la firma remota basata solo sull'hash tramite autorizzazione SAD.
uses sgcSign_KeyProvider_CSC, sgcSign_XAdES;
var oCSC: TsgcCSCKeyProvider; oX: TsgcXAdESSigner;
begin
oCSC := TsgcCSCKeyProvider.Create(nil);
oCSC.BaseURL := 'https://csc.example-qtsp.eu/csc/v2';
oCSC.AuthMethod := cscOAuth2;
oCSC.OAuthClientID := 'my-client-id';
oCSC.OAuthClientSecret := 'my-client-secret';
oCSC.CredentialID := oCSC.ListCredentials[0];
oCSC.PIN := '1234';
oCSC.OTP := '987654'; // pushed via SMS / app
oCSC.LoadCredentialInfo;
oX := TsgcXAdESSigner.Create(nil);
oX.KeyProvider := oCSC;
oX.Profile := spEIDAS;
oX.SignXML(vXML);
end;
Nove profili per il lavoro
Nove profili preconfigurati sono dedicati ai documenti del diritto del lavoro europeo (contratti di lavoro, buste paga, accordi di trasferimento):
| Profilo | Paese | Livello | C14N | TSA | OCSP |
|---|---|---|---|---|---|
spEmploymentDE | Germania | B-LT | Exclusive | Sì | Sì |
spEmploymentIT | Italia | B-LT | C14N 1.0 | Sì | Sì |
spEmploymentES | Spagna | B-T | Exclusive | Sì | No |
spEmploymentFR | Francia | B-T | Exclusive | Sì | No |
spEmploymentPL | Polonia | B-T | Exclusive | Sì | No |
spEmploymentAT | Austria | B-LT | Exclusive | Sì | Sì |
spEmploymentBE | Belgio | B-LT | Exclusive | Sì | Sì |
spEmploymentPT | Portogallo | B-LT | Exclusive | Sì | Sì |
spEmploymentNL | Paesi Bassi | B-T | Exclusive | Sì | No |
Una nuova demo EU_Employment include la pipeline completa (firma → pacchetto ASiC-E → verifica LOTL → classificazione QTSP).
Peppol BIS Billing 3.0 bulgaro
Il nuovo profilo TsgcProfilePeppolBG firma fatture UBL 2.1 bulgare (valuta BGN, IVA al 20%, BG VAT / EIK, IBAN BG, endpoint scheme ID 9926) a livello XAdES B-T con C14N exclusive. Le demo Delphi e C++Builder includono un modello di fattura completamente popolato.
uses sgcSign_XAdES, sgcSign_Types;
var oSigner: TsgcXAdESSigner;
begin
oSigner := TsgcXAdESSigner.Create(nil);
try
oSigner.KeyProvider := oPFX;
oSigner.TSAClient := oTSA;
oSigner.Profile := spPeppolBG;
oSigner.SignXMLFile('invoice_bg.xml', 'invoice_bg_signed.xml');
finally
oSigner.Free;
end;
end;
Integrazioni CI/CD
sgcSign Server include ora artefatti di prima classe per ogni pipeline comune:
- GitHub Actions — Action composita con firma Authenticode basata solo sull'hash.
- Azure DevOps — task nativo con integrazione secure-file.
- Jenkins — DSL di pipeline dichiarativa e libreria condivisa.
- Docker — immagine Windows Server Core e file
docker-compose. - Helm — chart Kubernetes per sgcSign Server in alta disponibilità.
Generatore di QR Code
Per TicketBAI, VeriFactu e profili simili che richiedono un codice QR sulla fattura stampabile, la nuova unit sgcSign_QRCode fornisce un generatore in puro Pascal che implementa ISO/IEC 18004 in modalità byte, tutti e quattro i livelli ECC, le versioni da 1 a 40, Reed-Solomon su GF(256), valutazione completa delle mask-penalty, con un renderer TBitmap. Nessuna DLL esterna, nessuna sorpresa di licenza.
uses sgcSign_QRCode, Graphics;
var
oMatrix: TQRMatrix;
oBmp: TBitmap;
begin
oMatrix := GenerateQRCode(
'https://tbai.eus/QURL/123456789-A?cr=42',
qrECM);
oBmp := TBitmap.Create;
try
RenderQRMatrix(oMatrix, oBmp, 5, 4); // 5 px / module, 4-module border
oBmp.SaveToFile('invoice_qr.bmp');
finally
oBmp.Free;
end;
end;
ECDSA P-256 / P-384 / P-521 e RSA-PSS
TsgcPEMKeyProvider ora importa chiavi private EC tramite Windows BCrypt CNG (ECCPRIVATEBLOB) e firma con output grezzo r||s per XML-DSig. Un nuovo metodo SignDataPSS produce firme RSA-PSS (SHA-256, salt = 32 byte) utilizzando BCRYPT_PAD_PSS, richiesto da un numero crescente di profili nazionali di fatturazione elettronica.
Sul lato verifica, TsgcSignatureVerifier importa chiavi pubbliche EC da BCRYPT_ECCPUBLIC_BLOB e convalida le firme ECDSA per le stesse tre curve sia nel SignatureValue XAdES sia nei percorsi di codice VerifyData grezzi.
Per rendere possibile tutto ciò, TsgcX509Certificate analizza ora l'estensione KeyUsage e la espone tramite la proprietà KeyUsage e gli helper HasKeyUsageDigitalSignature / HasKeyUsageNonRepudiation, e la nuova proprietà PublicKeyParameters espone i parametri TLV grezzi dell'AlgorithmIdentifier (l'OID della curva nominata per i certificati EC).
Overload WideString per Delphi 7
Per i chiamanti che passano testo non ACP (KSeF polacco, myDATA greco, Peppol bulgaro, ecc.), l'API pubblica di firma e verifica ora espone gli overload WideString su TsgcXAdESSigner.SignXML, SignXMLDetached, SignXMLEnveloping (e i metodi corrispondenti su TsgcDocumentSigner e TsgcSignatureVerifier). Questo garantisce un Unicode senza perdite in ingresso/uscita su Delphi 7, senza round-trip ACP, ed è equivalente agli overload string su Delphi 2009+.
Correzioni di conformità e affidabilità
Il lotto di bug-fix della 2026.5 chiude un lungo elenco di problemi XAdES / PFX / verifier riscontrati su endpoint reali delle autorità fiscali.
TsgcDocumentSignerora produce correttamente XAdES per i profili AdES. Internamente delega aTsgcXAdESSignerper il percorsosfXAdES, e solleva un errore chiaro persfPAdES/sfCAdES(usare i firmatari dedicati). Una nuova proprietà pubblicataFormat: TsgcSignatureFormat(predefinitasfXAdES) rende la scelta esplicita. Le versioni precedenti emettevano XML-DSig semplice indipendentemente dal profilo, cosa che i servizi nazionali di fatturazione elettronica rifiutavano.TsgcPFXKeyProviderguadagna una nuova proprietà pubblicataHashAlgorithm(predefinitahaSHA256), eTsgcXAdESSignerora inoltra l'hash del profilo attivo ai provider PFX. Le fatture FacturaeB2B firmate con PFX risultano ora correttamente RSA-SHA1, risolvendo il rifiuto FACe INVALID_INVOICE-122 «los datos de la firma no son correctos».TsgcPFXKeyProviderora supporta i file P12 moderni:PKCS12_PREFER_CNG_KSP, iterazione e probe multi-certificato, acquisizione a due stadi (ONLY_NCRYPTseguito daPREFER_NCRYPT) e firma CNG tramiteNCryptSignHash.- Conformità XAdES KSeF / ETSI — wrapper
SigningCertificateV1, emissione condizionale diSignaturePolicyIdentifier,X509SerialNumberdecimale,SignedPropertiesa singolo build (correzione race condition sul clock), trasformazioni exc-c14n esplicite sul riferimentoSignedProperties, e una nuova proprietàSignatureParentElement.TsgcSignatureVerifierora risolveURI=#<Id>tramite lookup per Id di elemento. - Parsing delle estensioni X.509 — il contenuto del tag v3
[3] EXPLICIT Extensionsveniva incapsulato due volte, saltando silenziosamenteKeyUsage,ExtendedKeyUsage, AIA, CDP, SubjectAltName e BasicConstraints su ogni certificato. Risolto. - Tag XML auto-chiusi —
ExtractFullElementgestisce ora correttamente<ds:DigestMethod Algorithm="…/sha1"/>. Le versioni precedenti utilizzavano per impostazione predefinita SHA-256, interrompendo la verifica FacturaeB2B con "Digest length mismatch for Reference 0". - Fallback C14N inclusivo —
TsgcSignatureVerifierapplica C14N inclusivo implicito ai riferimenti a frammento / URI vuoto che omettono una trasformazione esplicita, secondo XML-DSig §4.3.3.2. Risolve "Digest value mismatch" sui riferimenti KeyInfo e body nei profili C14N inclusivo (FacturaeB2B). - Hardening PEM — correzione di
ReadFileContentUnicode, decodifica PKCS#8 a due passaggi, keyspecAT_KEYEXCHANGE, container CSP con suffisso GUID, PKCS#8 cifrato nativo (PBES2 / PBKDF2 / AES-CBC) tramite BCrypt,LoadCertificateOnlye riconoscimento dei marker EC. - Manutenzione design-time — tutti e nove i componenti firmatario / verificatore puliscono ora automaticamente i riferimenti collegati tramite
Notification(opRemove), eliminando i puntatori pendenti quando un key provider o un TSA client viene rimosso dal form. - Igiene di build — W1000 (UTF8Decode) in
sgcSign_ASiCrisolto tramite un fallback{$IFDEF UNICODE} UTF8ToString; avvisi di codice morto H2077 / H2219 ripuliti insgcSign_XAdESesgcSign_TrustList.
Aggiornamento
2026.5 è un aggiornamento drop-in per i progetti 2026.4 esistenti. L'unico cambiamento comportamentale a cui prestare attenzione è TsgcDocumentSigner: il codice che si affidava al fatto che emettesse XML-DSig semplice per i profili AdES produrrà ora correttamente XAdES, è ciò che le autorità fiscali hanno richiesto, ma se il test di integrazione era ancorato all'output legacy sarà necessario aggiornare i file golden.
I clienti con un abbonamento attivo possono scaricare la nuova build dall'area clienti. Gli utenti trial possono ottenere l'installer aggiornato su esegece.com/products/sgcsign/sgcsign-download.
Domande, feedback o aiuto per la migrazione? Contattaci — riceverai una risposta dalle persone che hanno scritto il codice.
