Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Tcl) Signed Zip as Base64 with XAdES-BESThis example is to help companies implement a solution for sending XAdES-BES to the Polish government for reporting purposes. Specifically: Przed podpisaniem deklaracja zbiorcza (PIT-11Z, PIT-8CZ, PIT-40Z, PIT-RZ) musi zostać The example demonstrates the following:
This example will also show the reverse:
load ./chilkat.dll # This example assumes the Chilkat API to have been previously unlocked. # See Global Unlock Sample for sample code. # Zip the PIT-11Z.xml to create PIT-11Z.zip (not as a .zip file, but in-memory). set sbXmlToZip [new_CkStringBuilder] set success [CkStringBuilder_LoadFile $sbXmlToZip "qa_data/xml/PIT-11Z.xml" "utf-8"] if {$success != 1} then { puts "Failed to load the XML to be zipped." delete_CkStringBuilder $sbXmlToZip exit } set zip [new_CkZip] # Initialize the zip object. No file is created in this call. # It should always return 1. set success [CkZip_NewZip $zip "PIT-11Z.zip"] # Add the XML to be zipped. # entry is a CkZipEntry set entry [CkZip_AppendString $zip "PIT-11Z.xml" [CkStringBuilder_getAsString $sbXmlToZip]] delete_CkZipEntry $entry # Write the zip to a BinData object. set bdZip [new_CkBinData] CkZip_WriteBd $zip $bdZip # The contents of the bdZip will be retrieved in base64 format when needed below.. set gen [new_CkXmlDSigGen] CkXmlDSigGen_put_SigLocation $gen "" CkXmlDSigGen_put_SigLocationMod $gen 0 CkXmlDSigGen_put_SigId $gen "Signature_2a8df7f8-b958-40cc-83f6-edb53b837347_19" CkXmlDSigGen_put_SigNamespacePrefix $gen "ds" CkXmlDSigGen_put_SigNamespaceUri $gen "http://www.w3.org/2000/09/xmldsig#" CkXmlDSigGen_put_SigValueId $gen "SignatureValue_2a8df7f8-b958-40cc-83f6-edb53b837347_52" CkXmlDSigGen_put_SignedInfoId $gen "SignedInfo_2a8df7f8-b958-40cc-83f6-edb53b837347_41" CkXmlDSigGen_put_SignedInfoCanonAlg $gen "C14N" CkXmlDSigGen_put_SignedInfoDigestMethod $gen "sha1" # Set the KeyInfoId before adding references.. CkXmlDSigGen_put_KeyInfoId $gen "KeyInfo_2a8df7f8-b958-40cc-83f6-edb53b837347_24" # Create an Object to be added to the Signature. set object1 [new_CkXml] CkXml_put_Tag $object1 "xades:QualifyingProperties" CkXml_AddAttribute $object1 "xmlns:xades" "http://uri.etsi.org/01903/v1.3.2#" CkXml_AddAttribute $object1 "Id" "QualifyingProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_43" CkXml_AddAttribute $object1 "Target" "#Signature_2a8df7f8-b958-40cc-83f6-edb53b837347_19" CkXml_UpdateAttrAt $object1 "xades:SignedProperties" 1 "Id" "SignedProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_4e" CkXml_UpdateAttrAt $object1 "xades:SignedProperties|xades:SignedSignatureProperties" 1 "Id" "SignedSignatureProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_0a" # Chilkat will replace the strings "TO BE GENERATED BY CHILKAT" with actual values when the signature is created. CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningTime" "TO BE GENERATED BY CHILKAT" # Note: It may be that http://www.w3.org/2001/04/xmlenc#sha256 is needed in the following line instead of http://www.w3.org/2000/09/xmldsig#sha1 CkXml_UpdateAttrAt $object1 "xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificate|xades:Cert|xades:CertDigest|ds:DigestMethod" 1 "Algorithm" "http://www.w3.org/2000/09/xmldsig#sha1" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificate|xades:Cert|xades:CertDigest|ds:DigestValue" "TO BE GENERATED BY CHILKAT" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificate|xades:Cert|xades:IssuerSerial|ds:X509IssuerName" "TO BE GENERATED BY CHILKAT" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningCertificate|xades:Cert|xades:IssuerSerial|ds:X509SerialNumber" "TO BE GENERATED BY CHILKAT" CkXml_UpdateAttrAt $object1 "xades:SignedProperties|xades:SignedDataObjectProperties" 1 "Id" "SignedDataObjectProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_4b" CkXml_UpdateAttrAt $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat" 1 "ObjectReference" "#Reference1_2a8df7f8-b958-40cc-83f6-edb53b837347_27" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:Description" "MIME-Version: 1.0\r\nContent-Type: application/zip\r\nContent-Transfer-Encoding: binary\r\nContent-Disposition: filename="PIT-11Z.zip"" CkXml_UpdateAttrAt $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Identifier" 1 "Qualifier" "OIDAsURI" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Identifier" "http://www.certum.pl/OIDAsURI/signedFile/1.2.616.1.113527.3.1.1.3.1" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:Description" "Opis formatu dokumentu oraz jego pelna nazwa" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:ObjectIdentifier|xades:DocumentationReferences|xades:DocumentationReference" "http://www.certum.pl/OIDAsURI/signedFile.pdf" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:DataObjectFormat|xades:MimeType" "application/zip" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:CommitmentTypeIndication|xades:CommitmentTypeId|xades:Identifier" "http://uri.etsi.org/01903/v1.2.2#ProofOfApproval" CkXml_UpdateChildContent $object1 "xades:SignedProperties|xades:SignedDataObjectProperties|xades:CommitmentTypeIndication|xades:AllSignedDataObjects" "" CkXml_UpdateAttrAt $object1 "xades:UnsignedProperties" 1 "Id" "UnsignedProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_55" # Emit XML in compact (single-line) format to avoid whitespace problems. CkXml_put_EmitCompact $object1 1 CkXmlDSigGen_AddObject $gen "" [CkXml_getXml $object1] "" "" # Create an Object to be added to the Signature. # This is where we add the base64 representation of the PIT-11Z.zip CkXmlDSigGen_AddObject $gen "Object1_2a8df7f8-b958-40cc-83f6-edb53b837347" [CkBinData_getEncoded $bdZip "base64"] "" "http://www.w3.org/2000/09/xmldsig#base64" # -------- Reference 1 -------- CkXmlDSigGen_AddObjectRef $gen "Object1_2a8df7f8-b958-40cc-83f6-edb53b837347" "sha1" "C14N_WithComments" "" "" CkXmlDSigGen_SetRefIdAttr $gen "Object1_2a8df7f8-b958-40cc-83f6-edb53b837347" "Reference1_2a8df7f8-b958-40cc-83f6-edb53b837347_27" # -------- Reference 2 -------- CkXmlDSigGen_AddObjectRef $gen "SignedProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_4e" "sha1" "" "" "http://uri.etsi.org/01903#SignedProperties" CkXmlDSigGen_SetRefIdAttr $gen "SignedProperties_2a8df7f8-b958-40cc-83f6-edb53b837347_4e" "SignedProperties-Reference_2a8df7f8-b958-40cc-83f6-edb53b837347_28" # 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_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert exit } CkXmlDSigGen_SetX509Cert $gen $cert 1 CkXmlDSigGen_put_KeyInfoType $gen "X509Data" CkXmlDSigGen_put_X509Type $gen "Certificate" # This will be an enveloping signature where the Signature element # is the XML document root, the signed data is contained within Object # tag(s) within the Signature. # Therefore, pass an empty sbXml to CreateXmlDsigSb. set sbXml [new_CkStringBuilder] # The Polish government's XmlDSig implementation requires that we reproduce an attribute-sorting error. # (This is an error in the XML canonicalization that is not noticed when both the signature-creation code and signature-verification code use # the same XML canonicalization implementation w/ the bug.) CkXmlDSigGen_put_Behaviors $gen "AttributeSortingBug,CompactSignedXml" # Sign the XML... set success [CkXmlDSigGen_CreateXmlDSigSb $gen $sbXml] if {$success != 1} then { puts [CkXmlDSigGen_lastErrorText $gen] delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml exit } # ----------------------------------------------- # Save the signed XML to a file. set success [CkStringBuilder_WriteFile $sbXml "qa_output/signedXml.xml" "utf-8" 0] puts [CkStringBuilder_getAsString $sbXml] # ---------------------------------------- # Verify the signature we just produced... set verifier [new_CkXmlDSig] set success [CkXmlDSig_LoadSignatureSb $verifier $sbXml] if {$success != 1} then { puts [CkXmlDSig_lastErrorText $verifier] delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier exit } set verified [CkXmlDSig_VerifySignature $verifier 1] if {$verified != 1} then { puts [CkXmlDSig_lastErrorText $verifier] delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier exit } puts "This signature was successfully verified." # ------------------------------------ # Finally, let's extract the .zip from the signed XML, and then unzip the original PIT-11Z.xml from the in-memory zip. set xml [new_CkXml] CkXml_LoadSb $xml $sbXml 1 # The base64 image of the PIT-11Z.zip is in the 2nd ds:Object child of the ds:Signature (the ds:Signature is the root element of the signed XML). # (ds:Object[0] would be the 1st ds:Object child. Index 1 is the 2nd ds:Object child.) set strZipBase64 [CkXml_getChildContent $xml "ds:Object[1]"] CkBinData_Clear $bdZip CkBinData_AppendEncoded $bdZip $strZipBase64 "base64" if {[CkBinData_get_NumBytes $bdZip] == 0} then { puts "Something went wrong.. we dont' have any data.." delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier delete_CkXml $xml exit } set success [CkZip_OpenBd $zip $bdZip] if {$success != 1} then { puts [CkZip_lastErrorText $zip] delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier delete_CkXml $xml exit } # Get the 1st file in the zip, which should be the PIT-11Z.xml set entry [CkZip_GetEntryByIndex $zip 0] if {[CkZip_get_LastMethodSuccess $zip] != 1} then { puts "Zip contains no files..." delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier delete_CkXml $xml exit } # Get the XML: set origXml [CkZipEntry_unzipToString $entry 0 "utf-8"] puts "Original XML extracted from base64 zip:" puts "$origXml" delete_CkZipEntry $entry delete_CkStringBuilder $sbXmlToZip delete_CkZip $zip delete_CkBinData $bdZip delete_CkXmlDSigGen $gen delete_CkXml $object1 delete_CkCert $cert delete_CkStringBuilder $sbXml delete_CkXmlDSig $verifier delete_CkXml $xml |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.