Create XAdES-T Signed XML
See more XAdES Examples
This example signs XML using the XAdES-T profile. XAdES-T is a profile within the XAdES standard that adds support for secure timestamping of signatures.Secure timestamping involves adding a timestamp to the signature, indicating the exact time when the signature was applied.
Timestamping enhances the long-term validity of signatures by providing evidence that the signature existed at a specific point in time, even if the signer's certificate has expired or been revoked.
XAdES-T signatures include elements for embedding timestamp data within the XML signature, along with information about the timestamp authority and the timestamp verification process.
XAdES-T signatures are suitable for scenarios where long-term validity and integrity of signatures are essential, such as in legal and regulatory contexts where archived documents may need to be validated years or decades later.
Chilkat Xbase++ Downloads
LOCAL nSuccess
LOCAL oXmlToSign
LOCAL oGen
LOCAL oObject1
LOCAL oObject2
LOCAL oCert
LOCAL oJsonTsa
LOCAL oSbXml
LOCAL oVerifier
LOCAL nNumSigs
LOCAL nVerifyIdx
LOCAL nVerified
nSuccess := 0
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
nSuccess := 1
// Create the XML to be signed...
// Use this online tool to generate code from sample XML:
// Generate Code to Create XML
// <?xml version="1.0" encoding="UTF-8"?>
// <es:Dossier xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns="http://uri.etsi.org/01903/v1.3.2#" xmlns:es="https://www.microsec.hu/ds/e-szigno30#" xsi:schemaLocation="https://www.microsec.hu/ds/e-szigno30# https://www.microsec.hu/ds/e-szigno30.xsd">
// <es:DossierProfile Id="PObject0" OBJREF="Object0">
// <es:Title>e-akta.es3</es:Title>
// <es:E-category>electronic dossier</es:E-category>
// <es:CreationDate>2022-12-02T07:55:16Z</es:CreationDate>
// </es:DossierProfile>
// <es:Documents Id="Object0"/>
// </es:Dossier>
oXmlToSign := CreateObject("Chilkat.Xml")
oXmlToSign:Tag := "es:Dossier"
oXmlToSign:AddAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
oXmlToSign:AddAttribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
oXmlToSign:AddAttribute("xmlns", "http://uri.etsi.org/01903/v1.3.2#")
oXmlToSign:AddAttribute("xmlns:es", "https://www.microsec.hu/ds/e-szigno30#")
oXmlToSign:AddAttribute("xsi:schemaLocation", "https://www.microsec.hu/ds/e-szigno30# https://www.microsec.hu/ds/e-szigno30.xsd")
oXmlToSign:UpdateAttrAt("es:DossierProfile", 1, "Id", "PObject0")
oXmlToSign:UpdateAttrAt("es:DossierProfile", 1, "OBJREF", "Object0")
oXmlToSign:UpdateChildContent("es:DossierProfile|es:Title", "e-akta.es3")
oXmlToSign:UpdateChildContent("es:DossierProfile|es:E-category", "electronic dossier")
oXmlToSign:UpdateChildContent("es:DossierProfile|es:CreationDate", "2022-12-02T07:55:16Z")
oXmlToSign:UpdateAttrAt("es:Documents", 1, "Id", "Object0")
oGen := CreateObject("Chilkat.XmlDSigGen")
oGen:SigLocation := "es:Dossier"
oGen:SigLocationMod := 0
oGen:SigId := "S9fe8096e-2cac-415d-9222-f6cf2ecb314b"
oGen:SigValueId := "VS9fe8096e-2cac-415d-9222-f6cf2ecb314b"
oGen:SignedInfoId := "SIS9fe8096e-2cac-415d-9222-f6cf2ecb314b"
oGen:SignedInfoCanonAlg := "EXCL_C14N"
oGen:SignedInfoDigestMethod := "sha256"
// Set the KeyInfoId before adding references..
oGen:KeyInfoId := "KS9fe8096e-2cac-415d-9222-f6cf2ecb314b"
// Create an Object to be added to the Signature.
oObject1 := CreateObject("Chilkat.Xml")
oObject1:Tag := "es:SignatureProfile"
oObject1:AddAttribute("Id", "PS9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject1:AddAttribute("OBJREF", "Object0")
oObject1:AddAttribute("SIGREF", "S9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject1:AddAttribute("SIGREFLIST", "#Object0 #PS9fe8096e-2cac-415d-9222-f6cf2ecb314b #PObject0 #XS9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject1:UpdateChildContent("es:SignerName", "EC Minősített-Tesztelő Péterke")
oObject1:UpdateChildContent("es:SDPresented", "false")
oObject1:UpdateChildContent("es:Type", "signature")
oObject1:UpdateAttrAt("es:Generator|es:Program", 1, "name", "e-Szigno")
oObject1:UpdateAttrAt("es:Generator|es:Program", 1, "version", "3.3.6.8")
oObject1:UpdateAttrAt("es:Generator|es:Device", 1, "name", "OpenSSL 1.1.1n 15 Mar 2022")
oObject1:UpdateAttrAt("es:Generator|es:Device", 1, "type", "")
oGen:AddObject("O1S9fe8096e-2cac-415d-9222-f6cf2ecb314b", oObject1:GetXml(), "", "")
// Create an Object to be added to the Signature.
oObject2 := CreateObject("Chilkat.Xml")
oObject2:Tag := "QualifyingProperties"
oObject2:AddAttribute("Target", "#S9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject2:AddAttribute("Id", "QPS9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject2:UpdateAttrAt("SignedProperties", 1, "Id", "XS9fe8096e-2cac-415d-9222-f6cf2ecb314b")
oObject2:UpdateChildContent("SignedProperties|SignedSignatureProperties|SigningTime", "TO BE GENERATED BY CHILKAT")
oObject2:UpdateAttrAt("SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|CertDigest|ds:DigestMethod", 1, "Algorithm", "http://www.w3.org/2001/04/xmlenc#sha256")
oObject2:UpdateChildContent("SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|CertDigest|ds:DigestValue", "TO BE GENERATED BY CHILKAT")
oObject2:UpdateChildContent("SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|IssuerSerialV2", "TO BE GENERATED BY CHILKAT")
oObject2:UpdateChildContent("SignedProperties|SignedSignatureProperties|SignaturePolicyIdentifier|SignaturePolicyImplied", "")
oObject2:UpdateChildContent("SignedProperties|SignedSignatureProperties|SignerRoleV2|ClaimedRoles|ClaimedRole", "tesztelő")
// Here we have the EncapsulatedTimestamp found in the unsigned signature properties.
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp", 1, "Id", "T72cb4961-4326-4319-857a-7cf55e7ef899")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|ds:CanonicalizationMethod", 1, "Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|EncapsulatedTimeStamp", 1, "Id", "ET72cb4961-4326-4319-857a-7cf55e7ef899")
oObject2:UpdateChildContent("UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|EncapsulatedTimeStamp", "TO BE GENERATED BY CHILKAT")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|TimeStampValidationData", 1, "xmlns", "http://uri.etsi.org/01903/v1.4.1#")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|CertificateValues", 1, "Id", "CV18c7702d-d45b-44bc-853a-a720f41053cd")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate", 1, "Id", "EC42db04c8-1422-407b-8c42-189353a55268")
oObject2:UpdateChildContent("UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate", "BASE64_CONTENT")
oObject2:UpdateAttrAt("UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate[1]", 1, "Id", "EC04728b44-a32c-46c1-b9bb-85b1f6b3c7d3")
oObject2:UpdateChildContent("UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate[1]", "BASE64_CONTENT")
oGen:AddObject("O2S9fe8096e-2cac-415d-9222-f6cf2ecb314b", oObject2:GetXml(), "", "")
// -------- Reference 1 --------
oGen:AddSameDocRef("Object0", "sha256", "EXCL_C14N", "", "")
oGen:SetRefIdAttr("Object0", "Re1f816c4-7898-4544-9b41-f4156dc0c528")
// -------- Reference 2 --------
oGen:AddObjectRef("PS9fe8096e-2cac-415d-9222-f6cf2ecb314b", "sha256", "EXCL_C14N", "", "")
oGen:SetRefIdAttr("PS9fe8096e-2cac-415d-9222-f6cf2ecb314b", "Ra873b616-e568-4c38-ae94-27fbff67cc43")
// -------- Reference 3 --------
oGen:AddSameDocRef("PObject0", "sha256", "EXCL_C14N", "", "")
oGen:SetRefIdAttr("PObject0", "Ra5d85948-5d6a-4914-8c32-242f5d6d9e81")
// -------- Reference 4 --------
oGen:AddObjectRef("XS9fe8096e-2cac-415d-9222-f6cf2ecb314b", "sha256", "EXCL_C14N", "", "http://uri.etsi.org/01903#SignedProperties")
oGen:SetRefIdAttr("XS9fe8096e-2cac-415d-9222-f6cf2ecb314b", "Ra7412a43-dc05-4e0a-ac84-e9a070214757")
// Provide a certificate + private key. (PFX password is test123)
oCert := CreateObject("Chilkat.Cert")
nSuccess := oCert:LoadPfxFile("qa_data/pfx/cert_test123.pfx", "test123")
IF (nSuccess != 1)
? oCert:LastErrorText
oXmlToSign:destroy()
oGen:destroy()
oObject1:destroy()
oObject2:destroy()
oCert:destroy()
RETURN
ENDIF
oGen:SetX509Cert(oCert, 1)
oGen:KeyInfoType := "X509Data"
oGen:X509Type := "Certificate"
// -------------------------------------------------------------------------------------------
// To have the EncapsulatedTimeStamp automatically added, we only need to do 2 things.
// 1) Add the <xades:EncapsulatedTimeStamp Encoding="http://uri.etsi.org/01903/v1.2.2#DER">TO BE GENERATED BY CHILKAT</xades:EncapsulatedTimeStamp>
// to the unsigned properties.
// 2) Specify the TSA URL (Timestamping Authority URL).
// Here we specify the TSA URL:
// -------------------------------------------------------------------------------------------
oJsonTsa := CreateObject("Chilkat.JsonObject")
oJsonTsa:UpdateString("timestampToken.tsaUrl", "http://timestamp.digicert.com")
oJsonTsa:UpdateBool("timestampToken.requestTsaCert", 1)
oGen:SetTsa(oJsonTsa)
// Load XML to be signed...
oSbXml := CreateObject("Chilkat.StringBuilder")
oXmlToSign:GetXmlSb(oSbXml)
oGen:Behaviors := "IndentedSignature,OmitAlreadyDefinedSigNamespace"
// Sign the XML...
nSuccess := oGen:CreateXmlDSigSb(oSbXml)
IF (nSuccess != 1)
? oGen:LastErrorText
oXmlToSign:destroy()
oGen:destroy()
oObject1:destroy()
oObject2:destroy()
oCert:destroy()
oJsonTsa:destroy()
oSbXml:destroy()
RETURN
ENDIF
// -----------------------------------------------
// Save the signed XML to a file.
nSuccess := oSbXml:WriteFile("c:/temp/qa_output/signedXml.xml", "utf-8", 0)
? oSbXml:GetAsString()
// ----------------------------------------
// Verify the signatures we just produced...
oVerifier := CreateObject("Chilkat.XmlDSig")
nSuccess := oVerifier:LoadSignatureSb(oSbXml)
IF (nSuccess != 1)
? oVerifier:LastErrorText
oXmlToSign:destroy()
oGen:destroy()
oObject1:destroy()
oObject2:destroy()
oCert:destroy()
oJsonTsa:destroy()
oSbXml:destroy()
oVerifier:destroy()
RETURN
ENDIF
nNumSigs := oVerifier:NumSignatures
nVerifyIdx := 0
DO WHILE nVerifyIdx < nNumSigs
oVerifier:Selector := nVerifyIdx
nVerified := oVerifier:VerifySignature(1)
IF (nVerified != 1)
? oVerifier:LastErrorText
oXmlToSign:destroy()
oGen:destroy()
oObject1:destroy()
oObject2:destroy()
oCert:destroy()
oJsonTsa:destroy()
oSbXml:destroy()
oVerifier:destroy()
RETURN
ENDIF
nVerifyIdx := nVerifyIdx + 1
ENDDO
? "All signatures were successfully verified."
oXmlToSign:destroy()
oGen:destroy()
oObject1:destroy()
oObject2:destroy()
oCert:destroy()
oJsonTsa:destroy()
oSbXml:destroy()
oVerifier:destroy()