Sample code for 30+ languages & platforms
Lua

Create JPK_VAT XaDES-BES Signed XML

See more XAdES Examples

Demonstrates how to sign XML for JPK_VAT.

Chilkat Lua Downloads

Lua
local chilkat = require("chilkat")

-- This example requires the Chilkat API to have been previously unlocked.
-- See Global Unlock Sample for sample code.

-- This example will sign the following XML document:

-- <?xml version="1.0" encoding="utf-8"?>
-- <InitUpload xmlns="http://e-dokumenty.mf.gov.pl">
--     <DocumentType>JPK</DocumentType>
--     <Version>01.02.01.20160617</Version>
--     <EncryptionKey algorithm="RSA" encoding="Base64" mode="ECB" padding="PKCS#1">...</EncryptionKey>
--     <DocumentList>
--         <Document>
--             <FormCode schemaVersion="1-1" systemCode="JPK_VAT (3)">JPK_VAT</FormCode>
--             <FileName>JPK_VAT_3_v1-1_20181208.xml</FileName>
--             <ContentLength>8736</ContentLength>
--             <HashValue algorithm="SHA-256" encoding="Base64">JEEI1pItwh6dj/Xe1uts/x61qnjZ4DLHpkRMhmf1oQQ=</HashValue>
--             <FileSignatureList filesNumber="1">
--                 <Packaging>
--                     <SplitZip mode="zip" type="split"/>
--                 </Packaging>
--                 <Encryption>
--                     <AES block="16" mode="CBC" padding="PKCS#7" size="256">
--                         <IV bytes="16" encoding="Base64">FFsCRAPYJD3J6cRvd44UDA==</IV>
--                     </AES>
--                 </Encryption>
--                 <FileSignature>
--                     <OrdinalNumber>1</OrdinalNumber>
--                     <FileName>JPK_VAT_3_v1-1_20181208-000.xml.zip.aes</FileName>
--                     <ContentLength>16</ContentLength>
--                     <HashValue algorithm="MD5" encoding="Base64">BX2DTD3ASC/zF6aq/012Cg==</HashValue>
--                 </FileSignature>
--             </FileSignatureList>
--         </Document>
--     </DocumentList>
-- </InitUpload>

-- First we build the XML to be signed.
--
-- Use this online tool to generate the code from sample XML:
-- Generate Code to Create XML

local success = true
local xmlToSign = chilkat.Xml.new()
xmlToSign.tag = "InitUpload"
xmlToSign:add_attribute("xmlns", "http://e-dokumenty.mf.gov.pl")
xmlToSign:update_child_content("DocumentType", "JPK")
xmlToSign:update_child_content("Version", "01.02.01.20160617")
xmlToSign:update_attr_at("EncryptionKey", true, "algorithm", "RSA")
xmlToSign:update_attr_at("EncryptionKey", true, "encoding", "Base64")
xmlToSign:update_attr_at("EncryptionKey", true, "mode", "ECB")
xmlToSign:update_attr_at("EncryptionKey", true, "padding", "PKCS#1")
xmlToSign:update_child_content("EncryptionKey", "...")
xmlToSign:update_attr_at("DocumentList|Document|FormCode", true, "schemaVersion", "1-1")
xmlToSign:update_attr_at("DocumentList|Document|FormCode", true, "systemCode", "JPK_VAT (3)")
xmlToSign:update_child_content("DocumentList|Document|FormCode", "JPK_VAT")
xmlToSign:update_child_content("DocumentList|Document|FileName", "JPK_VAT_3_v1-1_20181208.xml")
xmlToSign:update_child_content("DocumentList|Document|ContentLength", "8736")
xmlToSign:update_attr_at("DocumentList|Document|HashValue", true, "algorithm", "SHA-256")
xmlToSign:update_attr_at("DocumentList|Document|HashValue", true, "encoding", "Base64")
xmlToSign:update_child_content("DocumentList|Document|HashValue", "JEEI1pItwh6dj/Xe1uts/x61qnjZ4DLHpkRMhmf1oQQ=")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList", true, "filesNumber", "1")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Packaging|SplitZip", true, "mode", "zip")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Packaging|SplitZip", true, "type", "split")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES", true, "block", "16")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES", true, "mode", "CBC")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES", true, "padding", "PKCS#7")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES", true, "size", "256")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES|IV", true, "bytes", "16")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|Encryption|AES|IV", true, "encoding", "Base64")
xmlToSign:update_child_content("DocumentList|Document|FileSignatureList|Encryption|AES|IV", "FFsCRAPYJD3J6cRvd44UDA==")
xmlToSign:update_child_content("DocumentList|Document|FileSignatureList|FileSignature|OrdinalNumber", "1")
xmlToSign:update_child_content("DocumentList|Document|FileSignatureList|FileSignature|FileName", "JPK_VAT_3_v1-1_20181208-000.xml.zip.aes")
xmlToSign:update_child_content("DocumentList|Document|FileSignatureList|FileSignature|ContentLength", "16")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|FileSignature|HashValue", true, "algorithm", "MD5")
xmlToSign:update_attr_at("DocumentList|Document|FileSignatureList|FileSignature|HashValue", true, "encoding", "Base64")
xmlToSign:update_child_content("DocumentList|Document|FileSignatureList|FileSignature|HashValue", "BX2DTD3ASC/zF6aq/012Cg==")

-- Also see the online tool to generate the code from sample already-signed XML:
-- Generate XML Signature Creation Code from an Already-Signed XML Sample

local gen = chilkat.XmlDSigGen.new()

gen.sig_location = "InitUpload"
gen.sig_id = "id-1234"
gen.sig_namespace_prefix = "ds"
gen.sig_namespace_uri = "http://www.w3.org/2000/09/xmldsig#"
gen.signed_info_canon_alg = "EXCL_C14N"
gen.signed_info_digest_method = "sha256"

-- Create an Object to be added to the Signature.
local object1 = chilkat.Xml.new()
object1.tag = "xades:QualifyingProperties"
object1:add_attribute("Target", "#id-1234")
object1:add_attribute("xmlns:xades", "http://uri.etsi.org/01903/v1.3.2#")
object1:update_attr_at("xades:SignedProperties", true, "Id", "xades-id-1234")
object1:update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningTime", "TO BE GENERATED BY CHILKAT")
object1:update_attr_at("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:CertDigest|ds:DigestMethod", true, "Algorithm", "http://www.w3.org/2001/04/xmlenc#sha256")
object1:update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:CertDigest|ds:DigestValue", "TO BE GENERATED BY CHILKAT")
object1:update_child_content("xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificateV2|xades:Cert|xades:IssuerSerialV2", "TO BE GENERATED BY CHILKAT")
object1:update_attr_at("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat", true, "ObjectReference", "#r-id-1")
object1:update_child_content("xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:MimeType", "text/xml")

gen:add_object("", object1:get_xml(), "", "")

-- -------- Reference 1 --------
local xml1 = chilkat.Xml.new()
xml1.tag = "ds:Transforms"
xml1:update_attr_at("ds:Transform", true, "Algorithm", "http://www.w3.org/TR/1999/REC-xpath-19991116")
xml1:update_child_content("ds:Transform|ds:XPath", "not(ancestor-or-self::ds:Signature)")
xml1:update_attr_at("ds:Transform[1]", true, "Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#")

gen:add_same_doc_ref2("", "sha256", xml1, "")
gen:set_ref_id_attr("", "r-id-1")

-- -------- Reference 2 --------
local xml2 = chilkat.Xml.new()
xml2.tag = "ds:Transforms"
xml2:update_attr_at("ds:Transform", true, "Algorithm", "http://www.w3.org/2001/10/xml-exc-c14n#")

gen:add_object_ref2("xades-id-1234", "sha256", xml2, "http://uri.etsi.org/01903#SignedProperties")

-- Provide a certificate + private key. (PFX password is test123)
-- See Load Certificate on Smartcard for an example showing how to load the cert from a smartcard..
local cert = chilkat.Cert.new()
success = cert:load_pfx_file("qa_data/pfx/cert_test123.pfx", "test123")
if not success then
    print(cert.last_error_text)
    return
end

gen:set_x509_cert(cert, true)

gen.key_info_type = "X509Data"
gen.x509_type = "Certificate"

-- Load XML to be signed...
local sbXml = chilkat.StringBuilder.new()
xmlToSign:get_xml_sb(sbXml)

gen.behaviors = "IndentedSignature,TransformSignatureXPath,IssuerSerialHex"

-- Sign the XML...
success = gen:create_xml_dsig_sb(sbXml)
if not success then
    print(gen.last_error_text)
    return
end

-- Save the signed XMl to a file.
success = sbXml:write_file("qa_output/signedXml.xml", "utf-8", false)

print(sbXml:get_as_string())

-- ----------------------------------------
-- Verify the signature we just produced...
local verifier = chilkat.XmlDSig.new()
success = verifier:load_signature_sb(sbXml)
if not success then
    print(verifier.last_error_text)
    return
end

local verified = verifier:verify_signature(true)
if not verified then
    print(verifier.last_error_text)
    return
end

print("This signature was successfully verified.")