Sample code for 30+ languages & platforms
Tcl

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 Tcl Downloads

Tcl

load ./chilkat.dll

set success 0

set success 1

# Create the XML to be signed...

# Use this online tool to generate code from sample XML: 
# Generate Code to Create XML

set xmlToSign [new_CkXml]

CkXml_put_Tag $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" 1 "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"

set gen [new_CkXmlDSigGen]

CkXmlDSigGen_put_SigLocation $gen "rDE"
CkXmlDSigGen_put_SigLocationMod $gen 0
CkXmlDSigGen_put_SigNamespacePrefix $gen ""
CkXmlDSigGen_put_SigNamespaceUri $gen "http://www.w3.org/2000/09/xmldsig#"
CkXmlDSigGen_put_SignedInfoCanonAlg $gen "C14N"
CkXmlDSigGen_put_SignedInfoDigestMethod $gen "sha256"

# -------- Reference 1 --------
set xml1 [new_CkXml]

CkXml_put_Tag $xml1 "Transforms"
CkXml_UpdateAttrAt $xml1 "Transform" 1 "Algorithm" "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
CkXml_UpdateAttrAt $xml1 "Transform[1]" 1 "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)
set cert [new_CkCert]

set success [CkCert_LoadPfxFile $cert "qa_data/pfx/cert_test123.pfx" "test123"]
if {$success != 1} then {
    puts [CkCert_lastErrorText $cert]
    delete_CkXml $xmlToSign
    delete_CkXmlDSigGen $gen
    delete_CkXml $xml1
    delete_CkCert $cert
    exit
}

CkXmlDSigGen_SetX509Cert $gen $cert 1

CkXmlDSigGen_put_KeyInfoType $gen "X509Data"
CkXmlDSigGen_put_X509Type $gen "Certificate"

# Load XML to be signed...
set sbXml [new_CkStringBuilder]

CkXml_GetXmlSb $xmlToSign $sbXml

CkXmlDSigGen_put_Behaviors $gen "IndentedSignature"

# Sign the XML...
set success [CkXmlDSigGen_CreateXmlDSigSb $gen $sbXml]
if {$success != 1} then {
    puts [CkXmlDSigGen_lastErrorText $gen]
    delete_CkXml $xmlToSign
    delete_CkXmlDSigGen $gen
    delete_CkXml $xml1
    delete_CkCert $cert
    delete_CkStringBuilder $sbXml
    exit
}

# -----------------------------------------------

# Save the signed XML to a file.
set success [CkStringBuilder_WriteFile $sbXml "c:/temp/qa_output/signedXml.xml" "utf-8" 0]

puts [CkStringBuilder_getAsString $sbXml]

# ----------------------------------------
# Verify the signatures we just produced...
set verifier [new_CkXmlDSig]

set success [CkXmlDSig_LoadSignatureSb $verifier $sbXml]
if {$success != 1} then {
    puts [CkXmlDSig_lastErrorText $verifier]
    delete_CkXml $xmlToSign
    delete_CkXmlDSigGen $gen
    delete_CkXml $xml1
    delete_CkCert $cert
    delete_CkStringBuilder $sbXml
    delete_CkXmlDSig $verifier
    exit
}

set numSigs [CkXmlDSig_get_NumSignatures $verifier]
set verifyIdx 0
while {$verifyIdx < $numSigs} {
    CkXmlDSig_put_Selector $verifier $verifyIdx
    set verified [CkXmlDSig_VerifySignature $verifier 1]
    if {$verified != 1} then {
        puts [CkXmlDSig_lastErrorText $verifier]
        delete_CkXml $xmlToSign
        delete_CkXmlDSigGen $gen
        delete_CkXml $xml1
        delete_CkCert $cert
        delete_CkStringBuilder $sbXml
        delete_CkXmlDSig $verifier
        exit
    }

    set verifyIdx [expr $verifyIdx + 1]
}
puts "All signatures were successfully verified."

delete_CkXml $xmlToSign
delete_CkXmlDSigGen $gen
delete_CkXml $xml1
delete_CkCert $cert
delete_CkStringBuilder $sbXml
delete_CkXmlDSig $verifier