AutoIt
AutoIt
Create JPK VAT metadata XML
See more RSA Examples
Demonstrates how to create the JPK VAT metadata XML (InitUpload) that will be signed using XADES.Chilkat AutoIt Downloads
Local $bSuccess = False
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; First build an InitUpload XML template
; Use this online tool to generate the code from the sample XML below:
; Generate Code to Create XML
; <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">F9EhKFec...uWqAWUIg==</EncryptionKey>
; <DocumentList>
; <Document>
; <FormCode schemaVersion="1-1" systemCode="JPK_VAT (3)">JPK_VAT</FormCode>
; <FileName>JPK_VAT_3_v1-1_20181201.xml</FileName>
; <ContentLength>8736</ContentLength>
; <HashValue algorithm="SHA-256" encoding="Base64">JFDI1pItwh6dj/Xe1uts/x61qnjZ4DLHpkZMhmf1oKQ=</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">z64oN9zXHt1+S3XACRSCYw==</IV>
; </AES>
; </Encryption>
; <FileSignature>
; <OrdinalNumber>1</OrdinalNumber>
; <FileName>JPK_VAT_3_v1-1_20181201-000.xml.zip.aes</FileName>
; <ContentLength>16</ContentLength>
; <HashValue algorithm="MD5" encoding="Base64">5NX0q1935fvMjLFV7E1yDw==</HashValue>
; </FileSignature>
; </FileSignatureList>
; </Document>
; </DocumentList>
; </InitUpload>
$oXml = ObjCreate("Chilkat.Xml")
$oXml.Tag = "InitUpload"
$oXml.AddAttribute("xmlns","http://e-dokumenty.mf.gov.pl")
$oXml.UpdateChildContent "DocumentType","JPK"
$oXml.UpdateChildContent "Version","01.02.01.20160617"
$oXml.UpdateAttrAt("EncryptionKey",True,"algorithm","RSA")
$oXml.UpdateAttrAt("EncryptionKey",True,"encoding","Base64")
$oXml.UpdateAttrAt("EncryptionKey",True,"mode","ECB")
$oXml.UpdateAttrAt("EncryptionKey",True,"padding","PKCS#1")
$oXml.UpdateChildContent "EncryptionKey","TO BE DETERMINED"
$oXml.UpdateAttrAt("DocumentList|Document|FormCode",True,"schemaVersion","1-1")
$oXml.UpdateAttrAt("DocumentList|Document|FormCode",True,"systemCode","JPK_VAT (3)")
$oXml.UpdateChildContent "DocumentList|Document|FormCode","JPK_VAT"
$oXml.UpdateChildContent "DocumentList|Document|FileName","JPK_VAT_3_v1-1_20181201.xml"
$oXml.UpdateChildContent "DocumentList|Document|ContentLength","9999"
$oXml.UpdateAttrAt("DocumentList|Document|HashValue",True,"algorithm","SHA-256")
$oXml.UpdateAttrAt("DocumentList|Document|HashValue",True,"encoding","Base64")
$oXml.UpdateChildContent "DocumentList|Document|HashValue","TO BE DETERMINED"
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList",True,"filesNumber","1")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Packaging|SplitZip",True,"mode","zip")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Packaging|SplitZip",True,"type","split")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES",True,"block","16")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES",True,"mode","CBC")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES",True,"padding","PKCS#7")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES",True,"size","256")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES|IV",True,"bytes","16")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|Encryption|AES|IV",True,"encoding","Base64")
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|Encryption|AES|IV","TO BE DETERMINED"
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|FileSignature|OrdinalNumber","1"
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|FileSignature|FileName","JPK_VAT_3_v1-1_20181201-000.xml.zip.aes"
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|FileSignature|ContentLength","9999"
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|FileSignature|HashValue",True,"algorithm","MD5")
$oXml.UpdateAttrAt("DocumentList|Document|FileSignatureList|FileSignature|HashValue",True,"encoding","Base64")
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|FileSignature|HashValue","TO BE DETERMINED"
; ------------------------------------------------------------
; Step 1: Load our JPK_VAT XML and update the DocumentList|Document|HashValue
; and DocumentList|Document|ContentLength
$oBdXml = ObjCreate("Chilkat.BinData")
$bSuccess = $oBdXml.LoadFile("qa_data/xml_dsig/jpk_vat/JPK_VAT_3_v1-1_20181201-000.xml")
If ($bSuccess <> True) Then
ConsoleWrite("Failed to load XML file." & @CRLF)
Exit
EndIf
$oXml.UpdateChildContentInt "DocumentList|Document|ContentLength",$oBdXml.NumBytes
$oCrypt = ObjCreate("Chilkat.Crypt2")
$oCrypt.HashAlgorithm = "sha256"
$oCrypt.EncodingMode = "base64"
$oXml.UpdateChildContent "DocumentList|Document|HashValue",$oCrypt.HashBdENC($oBdXml)
; ------------------------------------------------------------
; Step 2: Create a Zip archive containing the XML.
$oZip = ObjCreate("Chilkat.Zip")
; The filename we pass here doesn't matter because we won't actually be creating a .zip file.
$oZip.NewZip("anything.zip")
$oZip.AddBd("JPK_VAT_3_v1-1_20181201-000.xml",$oBdXml)
; Write the .zip file to a BinData object.
$oBdZip = ObjCreate("Chilkat.BinData")
$oZip.WriteBd($oBdZip)
; ------------------------------------------------------------
; Step 3: Generate a random 256-bit AES key (32-bytes)
$oPrng = ObjCreate("Chilkat.Prng")
$oBdAesKey = ObjCreate("Chilkat.BinData")
$oPrng.GenRandomBd(32,$oBdAesKey)
Local $sIvBytes = $oPrng.GenRandom(16,"base64")
; Store the IV (base64 string) in the XML.
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|Encryption|AES|IV",$sIvBytes
; ------------------------------------------------------------
; Step 4: AES encrypt our zip archive (the contents of bdZip)
$oCrypt.CipherMode = "cbc"
$oCrypt.KeyLength = 256
$oCrypt.CryptAlgorithm = "aes"
$oCrypt.PaddingScheme = 0
$oCrypt.SetEncodedIV $sIvBytes,"base64"
$oCrypt.SetEncodedKey $oBdAesKey.GetEncoded("base64"),"base64"
; AES by definition has a block size of 16.
$oCrypt.EncryptBd($oBdZip)
; bdZip now contains the AES encrypted data.
; Note: This is NOT the same as a zip where the contents are AES encrypted.
; In that case, we have an unencrypted zip structure with AES encrypted files within.
; In our case, the entire zip file image is encrypted.
; Save the bdZip to a file. This is what will get sent to e-dokumenty.mf.gov.pl
$bSuccess = $oBdZip.WriteFile("qa_output/JPK_VAT_3_v1-1_20181201-000.xml.zip.aes")
$oXml.UpdateChildContentInt "DocumentList|Document|FileSignatureList|FileSignature|ContentLength",$oBdZip.NumBytes
; ------------------------------------------------------------
; Step 4: RSA Encrypt the AES key using the public key certificate provided by the Ministry of Finance
$oCert = ObjCreate("Chilkat.Cert")
$bSuccess = $oCert.LoadFromFile("qa_data/pem/mf_public_rsa.pem")
If ($bSuccess = False) Then
ConsoleWrite($oCert.LastErrorText & @CRLF)
Exit
EndIf
$oPubKey = ObjCreate("Chilkat.PublicKey")
$oCert.GetPublicKey($oPubKey)
$oRsa = ObjCreate("Chilkat.Rsa")
$oRsa.UsePublicKey($oPubKey)
$oRsa.EncodingMode = "base64"
$oRsa.LittleEndian = False
; in-place RSA encrypt the contents of bdAesKey.
$oRsa.EncryptBd($oBdAesKey,False)
$oXml.UpdateChildContent "EncryptionKey",$oBdAesKey.GetEncoded("base64")
; Step 5: We forgot to get the MD5 hash of the AES encrypted zip.
; (I'm assuming we need the MD5 of the encrypted zip as opposed to the MD5 of the pre-encrypted zip..)
$oCrypt.HashAlgorithm = "md5"
$oXml.UpdateChildContent "DocumentList|Document|FileSignatureList|FileSignature|HashValue",$oCrypt.HashBdENC($oBdZip)
; At this point, the XML is prepared and the AES encrypted image of the zip file is written
; to a file (and also in bdZip).
Local $sFinalXml = $oXml.GetXml()
ConsoleWrite($sFinalXml & @CRLF)
$oXml.SaveXml("qa_output/jpk_vat.xml")
ConsoleWrite("Finished." & @CRLF)