Delphi DLL
Delphi DLL
Paraguay E-Invoicing Signed XML (SIFEN)
See more XML Digital Signatures Examples
Demonstrates how to sign XML for e-invoicing -- SISTEMA INTEGRADO DE FACTURACIÓN ELECTRÓNICA NACIONAL (SIFEN). This is for signing XML files that need to be submitted to a government agency (Country Paraguay, SIFEN / EKUATIA, Sistema Nacional de Facturacion Electrónica).Chilkat Delphi DLL Downloads
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, StringBuilder, XmlDSigGen, Xml, XmlDSig, Cert;
...
procedure TForm1.Button1Click(Sender: TObject);
var
success: Boolean;
xmlToSign: HCkXml;
gen: HCkXmlDSigGen;
xml1: HCkXml;
cert: HCkCert;
sbXml: HCkStringBuilder;
verifier: HCkXmlDSig;
numSigs: Integer;
verifyIdx: Integer;
verified: Boolean;
begin
success := False;
success := True;
// Create the XML to be signed...
// Use this online tool to generate code from sample XML:
// Generate Code to Create XML
xmlToSign := CkXml_Create();
CkXml_putTag(xmlToSign,'rDE');
CkXml_AddAttribute(xmlToSign,'xmlns','http://ekuatia.set.gov.py/sifen/xsd');
CkXml_AddAttribute(xmlToSign,'xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance');
CkXml_AddAttribute(xmlToSign,'xsi:schemaLocation','http://ekuatia.set.gov.py/sifen/xsd siRecepDE_v150.xsd');
CkXml_UpdateChildContent(xmlToSign,'dVerFor','150');
CkXml_UpdateAttrAt(xmlToSign,'DE',True,'Id','01800228774059001001501012022091519999999990');
CkXml_UpdateChildContent(xmlToSign,'DE|dDVId','0');
CkXml_UpdateChildContent(xmlToSign,'DE|dFecFirma','2022-09-15T10:23:05');
CkXml_UpdateChildContent(xmlToSign,'DE|dSisFact','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gOpeDE|iTipEmi','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gOpeDE|dDesTipEmi','Normal');
CkXml_UpdateChildContent(xmlToSign,'DE|gOpeDE|dCodSeg','999999999');
CkXml_UpdateChildContent(xmlToSign,'DE|gOpeDE|dInfoEmi','GENERADA DE PEDIDO 131043202');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|iTiDE','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dDesTiDE','Factura electr�nica');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dNumTim','18889014');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dEst','059');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dPunExp','001');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dNumDoc','0015010');
CkXml_UpdateChildContent(xmlToSign,'DE|gTimb|dFeIniT','2022-05-25');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|dFeEmiDE','2022-09-15T10:22:57');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|iTipTra','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|dDesTipTra','Venta de mercader�a');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|iTImp','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|dDesTImp','IVA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|cMoneOpe','PYG');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gOpeCom|dDesMoneOpe','Guarani');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dRucEm','80022877');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDVEmi','4');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|iTipCont','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|cTipReg','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dNomEmi','ABCDEF SA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dNomFanEmi','ABCDEF SA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDirEmi','Jos� Abcde Xyz N� 666 e/Abxyz123');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dNumCas','0');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dCompDir1','N/A');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dCompDir2','N/A');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|cDepEmi','12');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDesDepEmi','CENTRAL');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|cDisEmi','153');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDesDisEmi','CAPIATA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|cCiuEmi','1234');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDesCiuEmi','CAPIATA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dTelEmi','(022) 1111 000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dEmailE','somebody@example.com.py');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|dDenSuc','PUNTO 99');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|gActEco|cActEco','47721');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gEmis|gActEco|dDesActEco','COMERCIO AL POR MENOR DE PRODUCTOS');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|iNatRec','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|iTiOpe','2');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|cPaisRec','PRY');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dDesPaisRe','Paraguay');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|iTiContRec','2');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dRucRec','80082971');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dDVRec','9');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dNomRec','XXXXXXX');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dNomFanRec','XXXXXXX');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dNumCasRec','0');
CkXml_UpdateChildContent(xmlToSign,'DE|gDatGralOpe|gDatRec|dCodCliente','9999999');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamFE|iIndPres','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamFE|dDesIndPres','Operaci�n presencial');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|iCondOpe','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|dDCondOpe','Contado');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni|iTiPago','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni|dDesTiPag','Efectivo');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni|dMonTiPag','100000.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni|cMoneTiPag','PYG');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni|dDMoneTiPag','Guarani');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni[1]|iTiPago','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni[1]|dDesTiPag','Efectivo');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni[1]|dMonTiPag','73600.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni[1]|cMoneTiPag','PYG');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamCond|gPaConEIni[1]|dDMoneTiPag','Guarani');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|dCodInt','818181');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|dDesProSer','Widget Abc Xyz');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|cUniMed','77');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|dDesUniMed','UNI');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|dCantProSer','2.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gValorItem|dPUniProSer','16500.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gValorItem|dTotBruOpeItem','33000.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gValorItem|gValorRestaItem|dDescItem','3300.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gValorItem|gValorRestaItem|dPorcDesIt','20.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gValorItem|gValorRestaItem|dTotOpeItem','26400.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|iAfecIVA','1');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|dDesAfecIVA','Gravado IVA');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|dPropIVA','100');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|dTasaIVA','5');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|dBasGravIVA','25142.8571');
CkXml_UpdateChildContent(xmlToSign,'DE|gDtipDE|gCamItem|gCamIVA|dLiqIVAItem','1257.1429');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dSubExe','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dSub5','26400.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dSub10','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotOpe','26400.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotDesc','6600.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotDescGlotem','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotAntItem','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotAnt','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dPorcDescTotal','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dDescTotal','6600.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dAnticipo','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dRedon','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotGralOpe','26400.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dIVA5','1257.1429');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dIVA10','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTotIVA','1257.1429');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dBaseGrav5','25142.8571');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dBaseGrav10','0.0000');
CkXml_UpdateChildContent(xmlToSign,'DE|gTotSub|dTBasGraIVA','25142.8571');
gen := CkXmlDSigGen_Create();
CkXmlDSigGen_putSigLocation(gen,'rDE');
CkXmlDSigGen_putSigLocationMod(gen,0);
CkXmlDSigGen_putSigNamespacePrefix(gen,'');
CkXmlDSigGen_putSigNamespaceUri(gen,'http://www.w3.org/2000/09/xmldsig#');
CkXmlDSigGen_putSignedInfoCanonAlg(gen,'C14N');
CkXmlDSigGen_putSignedInfoDigestMethod(gen,'sha256');
// -------- Reference 1 --------
xml1 := CkXml_Create();
CkXml_putTag(xml1,'Transforms');
CkXml_UpdateAttrAt(xml1,'Transform',True,'Algorithm','http://www.w3.org/2000/09/xmldsig#enveloped-signature');
CkXml_UpdateAttrAt(xml1,'Transform[1]',True,'Algorithm','http://www.w3.org/2001/10/xml-exc-c14n#');
CkXmlDSigGen_AddSameDocRef2(gen,'01800228774059001001501012022091516941989060','sha256',xml1,'');
// Provide a certificate + private key. (PFX password is test123)
cert := CkCert_Create();
success := CkCert_LoadPfxFile(cert,'qa_data/pfx/cert_test123.pfx','test123');
if (success <> True) then
begin
Memo1.Lines.Add(CkCert__lastErrorText(cert));
Exit;
end;
CkXmlDSigGen_SetX509Cert(gen,cert,True);
CkXmlDSigGen_putKeyInfoType(gen,'X509Data');
CkXmlDSigGen_putX509Type(gen,'Certificate');
// Load XML to be signed...
sbXml := CkStringBuilder_Create();
CkXml_GetXmlSb(xmlToSign,sbXml);
CkXmlDSigGen_putBehaviors(gen,'IndentedSignature');
// Sign the XML...
success := CkXmlDSigGen_CreateXmlDSigSb(gen,sbXml);
if (success <> True) then
begin
Memo1.Lines.Add(CkXmlDSigGen__lastErrorText(gen));
Exit;
end;
// -----------------------------------------------
// Save the signed XML to a file.
success := CkStringBuilder_WriteFile(sbXml,'c:/temp/qa_output/signedXml.xml','utf-8',False);
Memo1.Lines.Add(CkStringBuilder__getAsString(sbXml));
// ----------------------------------------
// Verify the signatures we just produced...
verifier := CkXmlDSig_Create();
success := CkXmlDSig_LoadSignatureSb(verifier,sbXml);
if (success <> True) then
begin
Memo1.Lines.Add(CkXmlDSig__lastErrorText(verifier));
Exit;
end;
numSigs := CkXmlDSig_getNumSignatures(verifier);
verifyIdx := 0;
while verifyIdx < numSigs do
begin
CkXmlDSig_putSelector(verifier,verifyIdx);
verified := CkXmlDSig_VerifySignature(verifier,True);
if (verified <> True) then
begin
Memo1.Lines.Add(CkXmlDSig__lastErrorText(verifier));
Exit;
end;
verifyIdx := verifyIdx + 1;
end;
Memo1.Lines.Add('All signatures were successfully verified.');
CkXml_Dispose(xmlToSign);
CkXmlDSigGen_Dispose(gen);
CkXml_Dispose(xml1);
CkCert_Dispose(cert);
CkStringBuilder_Dispose(sbXml);
CkXmlDSig_Dispose(verifier);
end;