Eğitim: Delphi'de XAdES XML İmzalama

Düz bir XML faturasını alıp bir XAdES-B-T belgesi üreten pratik bir adım adım kılavuz — FatturaPA, FACTUR-X ve Avrupa genelindeki çoğu e-faturalama portalının gerektirdiği düzey. Sarmalanmış, sarmalayan ve ayrık imza paketlemesi arasında seçim yapacak, bir RFC 3161 zaman damgası ekleyecek ve karşı tarafın tam olarak ne göreceğini bilmek için sonucu doğrulayacaksınız.

XAdES-B-B / B-T / B-LT / B-LTA
Sarmalanmış / Sarmalayan / Ayrık
Delphi 7 – RAD Studio 13

Üç paketleme modu, tek motor

XAdES, W3C XML-DSig spesifikasyonunu zaman damgalama ve uzun vadeli doğrulama verileriyle genişletir. Herhangi bir şey imzalamadan önce, ds:Signature öğesinin nerede bulunacağına karar verin.

Sarmalanmış

ds:Signature öğesi, belge kökünün içine eklenir. Bu, FatturaPA, FACTUR-X-XAdES ve çoğu e-faturalama akışı tarafından kullanılan biçimdir. İmzalı XML hâlâ orijinal belgenin geçerli bir kopyasıdır — okuyucular anlamadıkları imza öğesini yok sayar.

Sarmalayan

Orijinal XML, ds:Signature'ın içinde bir ds:Object alt öğesi olur. Tek, bağımsız bir zarfa ihtiyaç duyduğunuzda ve mevcut tüketicilerin belgeyi ayrıştırmaya devam edip edemeyeceğini önemsemediğinizde yararlıdır.

Ayrık

İmza ayrı bir dosyada bulunur ve bir URI referansı aracılığıyla orijinal belgeyi gösterir. SAML, ebXML ve kaynak belgenin bayt bayt dokunulmamış kalması gereken herhangi bir akışta yaygındır.

Birimleri ekleyin

XAdES; XML imzalayıcısına, XAdES profiline ve bir anahtar sağlayıcıya ihtiyaç duyar. Bu eğitimde PFX kullanıyoruz; bir akıllı kartınız veya bir bulut HSM'niz varsa 10 sağlayıcıdan herhangi birini takın.

Delphi uses cümlesi

sgcSign_XML, XML imzalama çekirdeğidir. sgcSign_Profile_XAdES; düzeyi, dönüşümleri ve zaman damgası yapılandırmasını sunar. sgcSign_KeyProvider_PFX, diskten bir PKCS#12 dosyası yükler — en yaygın başlangıç noktası.

Uzun vadeli düzeyler (B-LT, B-LTA) için, iptal verilerinin getirilip gömülebilmesi için sgcSign_OCSP ve sgcSign_CRL'ye de ihtiyacınız vardır.

uXAdESSigning.pas
uses
  Classes, SysUtils,
  // sgc
  sgcSign_KeyProvider_PFX,
  sgcSign_XML,
  sgcSign_Profile_XAdES,
  sgcSign_TSA,
  sgcSign_OCSP,
  sgcSign_CRL,
  sgcSign_Verifier;

XML'i ve anahtarı yükleyin

İki giriş — imzalamak istediğiniz XML ve imzaladığınız PFX sertifikası.

PFX anahtar sağlayıcısı

TsgcPFXKeyProvider, PKCS#12 dosyasını Windows CNG aracılığıyla içe aktarır, bu da sertifikanın başlangıçta hangi CSP için verildiğine bakılmaksızın modern bir imzalama tutamacı elde ettiğiniz anlamına gelir. Aynı sağlayıcı Windows 7 ve sonrasında, 32 bit ve 64 bit çalışır.

Sağlayıcıyı tüm imzalama işlemi boyunca canlı tutun — XML imzalayıcısı, SignXML dönene kadar temel anahtar tutamacına başvurur.

step1-load.pas
var
  vXML: string;
  vKeyProvider: TsgcPFXKeyProvider;
begin
  vXML := TFile.ReadAllText('invoice.xml', TEncoding.UTF8);

  vKeyProvider := TsgcPFXKeyProvider.Create(nil);
  vKeyProvider.FileName := 'certificate.pfx';
  vKeyProvider.Password := 'secret';
  vKeyProvider.LoadFromFile;
end;

XAdES-B-T veya XAdES-B-LT seçin

B-T, bir imza zaman damgası ekler. B-LT ayrıca CA zincirini ve iptal verilerini gömer, böylece imza yıllarca doğrulanabilir kalır.

Profil yapılandırması

Level, AdES düzeyini seçer: xalB, xalT, xalLT, xalLTA. Packaging; xpkEnveloped (varsayılan), xpkEnveloping veya xpkDetached seçer.

Transforms listesi varsayılan olarak çoğu e-faturalama şemasının zorunlu kıldığı xtEnvelopedSignature + xtC14NExclusive'dir. Yalnızca belirli bir ülke profili kapsayıcı C14N veya özel bir XSLT dönüşümü istediğinde geçersiz kılın.

B-LT için OCSP.AutoFetch := True, imzalayıcıya zincirdeki her sertifika için OCSP yanıtlarını almasını ve bunları RevocationValues öğesinin içine gömmesini söyler. İmzalı XML daha sonra bir doğrulayıcının ihtiyaç duyduğu her şeyi taşır — doğrulama sırasında ağ çağrısı gerekmez.

step2-profile.pas
var
  vProfile: TsgcSignProfile_XAdES;
begin
  vProfile := TsgcSignProfile_XAdES.Create(nil);
  vProfile.Level := xalT;            // or xalLT, xalLTA
  vProfile.Packaging := xpkEnveloped;
  vProfile.HashAlgorithm := shaSHA256;

  // Timestamp authority for B-T and above
  vProfile.TSA.URL := 'https://freetsa.org/tsr';
  vProfile.TSA.HashAlgorithm := shaSHA256;

  // For B-LT: embed full chain and revocation data
  vProfile.OCSP.AutoFetch := True;
  vProfile.CRL.AutoFetch := True;
end;

İmzalayın — sarmalanmış, sarmalayan ve ayrık

Aynı TsgcSignXML bileşeni üç paketleme modunun tümünü işler — yalnızca Packaging özelliği farklıdır.

Sarmalanmış imza

Faturalar için varsayılan. İmza, belge kökünün içine eklenir ve kendisini özetten çıkarmak için sarmalanmış imza dönüşümünü kullanır.

Şema farkında yükler (FatturaPA, TicketBAI, KSeF) için, imzanın doğru XML ad alanını devralması için RootNamespace ayarlayın — ülke profilleri bunu otomatik olarak ayarlar.

step3-enveloped.pas
var
  vSigner: TsgcSignXML;
  vSigned: string;
begin
  vSigner := TsgcSignXML.Create(nil);
  try
    vSigner.KeyProvider := vKeyProvider;
    vSigner.Profile := vProfile;          // Packaging = xpkEnveloped
    vSigned := vSigner.SignXML(vXML);
    TFile.WriteAllText('invoice-signed.xml', vSigned, TEncoding.UTF8);
  finally
    vSigner.Free;
  end;
end;

Sarmalayan ve ayrık

Profildeki paketlemeyi değiştirin, diğer her şeyi aynı tutun. Ayrık imzalar için DetachedURI'yi imzalanan belgenin yoluna veya URL'sine ayarlayın; doğrulayıcı, verileri getirmek için bu referansa ihtiyaç duyar.

Geri bir ayrık imza aldığınızda, hem imza XML'ini hem de orijinal belge baytlarını VerifyDetached'e iletin — sgcSign özeti yeniden hesaplar ve bağlamayı onaylar.

step3-other.pas
// Enveloping: original XML wrapped in a ds:Object
vProfile.Packaging := xpkEnveloping;
vSigned := vSigner.SignXML(vXML);

// Detached: signature file points at invoice.xml
vProfile.Packaging := xpkDetached;
vProfile.DetachedURI := 'invoice.xml';
vSigned := vSigner.SignXML(vXML);
TFile.WriteAllText('invoice.sig.xml', vSigned, TEncoding.UTF8);

İmzalı XML'i doğrulayın

İş akışını yayınlamadan önce her imzalı belge doğrulanmalıdır.

Tek çağrı, tam rapor

VerifyXML; algılanan AdES düzeyi, imzalayan konusu, imza zaman damgası ve herhangi bir zincir veya iptal sorunuyla bir TsgcSignatureReport döndürür. Sarmalanmış imzalar için doğrulayıcı ds:Signature öğesini otomatik olarak bulur; ayrık imzalar için VerifyDetached kullanın ve orijinal belge baytlarını sağlayın.

Status, svValid ise özet eşleşir, sertifika zinciri güvenilir bir köke dayanır ve zaman damgası sağlamdır. StatusDetail'de sebebiyle svInvalid tipik başarısızlık modudur; svUnknown, doğrulayıcının bir OCSP yanıtlayıcısına veya CRL dağıtım noktasına ulaşamadığı anlamına gelir.

step4-verify.pas
var
  vVerifier: TsgcSignatureVerifier;
  vReport: TsgcSignatureReport;
begin
  vVerifier := TsgcSignatureVerifier.Create(nil);
  try
    vReport := vVerifier.VerifyXML(vSigned);
    Memo1.Lines.Add('Level:   ' + vReport.Signatures[0].LevelAsString);
    Memo1.Lines.Add('Status:  ' + vReport.Signatures[0].StatusAsString);
    Memo1.Lines.Add('Signer:  ' + vReport.Signatures[0].Subject);
    Memo1.Lines.Add('TSA:     ' +
      DateTimeToStr(vReport.Signatures[0].TimestampUTC));
  finally
    vVerifier.Free;
  end;
end;

Genellikle ne ters gider

Geliştiriciler ilk XAdES zarflarını imzaladığında en sık gördüğümüz sorunlar.

Boşluk ve kanonikleştirme

İmzalı bir XML'i güzel biçimlendirmek — bir metin düzenleyicide, bir IDE'de veya bir XSLT'den geçirerek — özeti bozar. Özel C14N her bayta duyarlıdır. İmzalı XML'i bayt olarak depolayın, bayt olarak taşıyın, asla yeniden biçimlendirmeyin.

Giriş belgesinde BOM

XML'in başındaki UTF-8 BOM'u, özellikle belge Notepad ile yazıldığında, eşleşmeyen özetlerin sık karşılaşılan bir kaynağıdır. İmzalamadan önce BOM'u kaldırın — sgcSign dahili olarak normalleştirir ancak diğer doğrulayıcılar bunu yapmayabilir.

FatturaPA xalLT gerektirir

İtalyan e-faturalama portalı, arşiv sırasında uzun vadeli iptal aramaları yapamadığı için XAdES-B-T'yi reddeder. OCSP yanıtının belgeyle birlikte gitmesi için OCSP.AutoFetch = True ile xalLT kullanın.

Ayrık imzalar ve URI çözümleme

DetachedURI göreli bir yolsa, doğrulayıcı bunu kendi çalışma dizinine göre çözer. Makineler arası akışlar için mutlak bir URL kullanın veya belge baytlarını doğrudan VerifyDetached'e iletin.

Buradan nereye gidilir

Ülke profilleri XAdES yapılandırmasını sizin için yapar. Sunucu, imzalamayı derleme çiftliği genelinde merkezileştirir.

Ülke Profilleri

VeriFactu, FatturaPA, KSeF, FACTUR-X, TicketBAI — tek bir sabit, her dönüşümü, algoritmayı ve gerekli özniteliği değiştirir.

Devamını okuyun →

PAdES Eğitimi

Aynı motor, XML yerine PDF'e uygulanır. İki biçimi yan yana karşılaştırmak için PAdES adım adım kılavuzunu okuyun.

Devamını okuyun →

sgcSign Server

REST API, GitHub Actions entegrasyonu, Docker ve Helm. İmzalamayı bireysel geliştiricilerden denetimli bir hizmete aktarın.

Devamını okuyun →

İlk XML'inizi imzalamaya hazır mısınız?

Denemeyi indirin, bu eğitimi kendi faturanız üzerinde çalıştırın, yayınladığınızda sgcSign'i lisanslayın.