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
(Objective-C) Apply 2nd Signature to sii.cl Factura Electrónica (Chile Servicio de Impuestos Internos)Demonstrates how to apply the 2nd signature an XML invoice according to Chilean Internal Revenue Service regulations.
#import <CkoXmlDSigGen.h> #import <CkoCert.h> #import <CkoXml.h> #import <CkoStringBuilder.h> // This example assumes the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. // In this example: Create sii.cl Factura Electr�nica (Chile Servicio de Impuestos Internos) // We signed XML structured like this: // <?xml version="1.0" encoding="iso-8859-1"?> // <DTE version="1.0" xmlns="http://www.sii.cl/SiiDte"> // <Documento ID="F11T22"> // ... // </Documento> // </DTE> // To get a signature like this: // <?xml version="1.0" encoding="iso-8859-1"?> // <DTE version="1.0" xmlns="http://www.sii.cl/SiiDte"> // <Documento ID="F11T22"> // ... // </Documento> // <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> // .. // </Signature> // </DTE> // Now we wish to wrap the result of the 1st example in the following and sign again: // <?xml version="1.0" encoding="iso-8859-1"?> // <EnvioDTE version="1.0" xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd"> // <SetDTE ID="NDTECHILE"> // <Caratula version="1.0"> // <RutEmisor>...</RutEmisor> // <RutEnvia>...</RutEnvia> // <RutReceptor>...</RutReceptor> // <FchResol>2014-08-22</FchResol> // <NroResol>80</NroResol> // <TmstFirmaEnv>2020-07-17T13:19:10</TmstFirmaEnv> // <SubTotDTE> // <TpoDTE>34</TpoDTE> // <NroDTE>1</NroDTE> // </SubTotDTE> // </Caratula> // <DTE version="1.0" xmlns="http://www.sii.cl/SiiDte"> // <Documento ID="F11T22">...</Documento> // <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">..</Signature> // </DTE> // </SetDTE> // </EnvioDTE> // The result will be this: // <?xml version="1.0" encoding="iso-8859-1"?> // <EnvioDTE version="1.0" xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd"> // <SetDTE ID="NDTECHILE"> // <Caratula version="1.0"> // <RutEmisor>...</RutEmisor> // <RutEnvia>...</RutEnvia> // <RutReceptor>...</RutReceptor> // <FchResol>2014-08-22</FchResol> // <NroResol>80</NroResol> // <TmstFirmaEnv>2020-07-17T13:19:10</TmstFirmaEnv> // <SubTotDTE> // <TpoDTE>34</TpoDTE> // <NroDTE>1</NroDTE> // </SubTotDTE> // </Caratula> // <DTE version="1.0" xmlns="http://www.sii.cl/SiiDte"> // <Documento ID="F11T22">...</Documento> // <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">..</Signature> // </DTE> // </SetDTE> // <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">..</Signature> // </EnvioDTE> CkoXmlDSigGen *gen = [[CkoXmlDSigGen alloc] init]; gen.SigLocation = @"EnvioDTE"; gen.SigLocationMod = [NSNumber numberWithInt:0]; gen.SigNamespacePrefix = @""; gen.SigNamespaceUri = @"http://www.w3.org/2000/09/xmldsig#"; gen.SignedInfoCanonAlg = @"C14N"; gen.SignedInfoDigestMethod = @"sha1"; // -------- Reference 1 -------- [gen AddSameDocRef: @"NDTECHILE" digestMethod: @"sha1" canonMethod: @"" prefixList: @"" refType: @""]; // Provide a certificate + private key. (PFX password is test123) CkoCert *cert = [[CkoCert alloc] init]; BOOL success = [cert LoadPfxFile: @"qa_data/pfx/cert_test123.pfx" password: @"test123"]; if (success != YES) { NSLog(@"%@",cert.LastErrorText); return; } [gen SetX509Cert: cert usePrivateKey: YES]; gen.KeyInfoType = @"X509Data+KeyValue"; gen.X509Type = @"Certificate"; // Here's the part where we must be very careful not to disturb the existing signature. // We want to encapsulate the existing signed XML like this: // <?xml version="1.0" encoding="iso-8859-1"?> // <EnvioDTE version="1.0" xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd"> // <SetDTE ID="NDTECHILE"> // <Caratula version="1.0"> // <RutEmisor>...</RutEmisor> // <RutEnvia>...</RutEnvia> // <RutReceptor>...</RutReceptor> // <FchResol>2014-08-22</FchResol> // <NroResol>80</NroResol> // <TmstFirmaEnv>2020-07-17T13:19:10</TmstFirmaEnv> // <SubTotDTE> // <TpoDTE>34</TpoDTE> // <NroDTE>1</NroDTE> // </SubTotDTE> // </Caratula> // <EXISTING_SIGNED_XML>HERE</EXISTING_SIGNED_XML> // </SetDTE> // <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">..</Signature> // </EnvioDTE> CkoXml *xml = [[CkoXml alloc] init]; xml.Tag = @"EnvioDTE"; [xml AddAttribute: @"version" value: @"1.0"]; [xml AddAttribute: @"xmlns" value: @"http://www.sii.cl/SiiDte"]; [xml AddAttribute: @"xmlns:xsi" value: @"http://www.w3.org/2001/XMLSchema-instance"]; [xml AddAttribute: @"xsi:schemaLocation" value: @"http://www.sii.cl/SiiDte EnvioDTE_v10.xsd"]; [xml UpdateAttrAt: @"SetDTE" autoCreate: YES attrName: @"ID" attrValue: @"NDTECHILE"]; [xml UpdateAttrAt: @"SetDTE|Caratula" autoCreate: YES attrName: @"version" attrValue: @"1.0"]; [xml UpdateChildContent: @"SetDTE|Caratula|RutEmisor" value: @"..."]; [xml UpdateChildContent: @"SetDTE|Caratula|RutEnvia" value: @"..."]; [xml UpdateChildContent: @"SetDTE|Caratula|RutReceptor" value: @"..."]; [xml UpdateChildContent: @"SetDTE|Caratula|FchResol" value: @"2014-08-22"]; [xml UpdateChildContent: @"SetDTE|Caratula|NroResol" value: @"80"]; [xml UpdateChildContent: @"SetDTE|Caratula|TmstFirmaEnv" value: @"2020-07-17T13:19:10"]; [xml UpdateChildContent: @"SetDTE|Caratula|SubTotDTE|TpoDTE" value: @"34"]; [xml UpdateChildContent: @"SetDTE|Caratula|SubTotDTE|NroDTE" value: @"1"]; [xml UpdateChildContent: @"SetDTE|EXISTING_SIGNED_XML" value: @"HERE"]; CkoStringBuilder *sbXml = [[CkoStringBuilder alloc] init]; [xml GetXmlSb: sbXml]; // Load our existing signed XML. // We cannot load it into a Chilkat XML object because we cannot allow anything to change, // not even indentation or whitespace. CkoStringBuilder *sbExisting = [[CkoStringBuilder alloc] init]; [sbExisting LoadFile: @"qa_data/xml_dsig/sii_cl/signed1.xml" charset: @"iso-8859-1"]; // However, we must remove the XML declarator, and we can trim the whitespace at the very front and back (i.e. whitespace completely outside the document). int numReplaced = [[sbExisting Replace: @"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" replacement: @""] intValue]; [sbExisting Trim]; // Insert the existing signed XML into the new XML document to be signed. numReplaced = [[sbXml Replace: @"<EXISTING_SIGNED_XML>HERE</EXISTING_SIGNED_XML>" replacement: [sbExisting GetAsString]] intValue]; // We now have the XML document ready for the 2nd signature to be applied... // Make sure we add the "SignExistingSignatures" behavior so that this signature includes the original signature in the digest. gen.Behaviors = @"IndentedSignature,SignExistingSignatures"; // Sign the XML... success = [gen CreateXmlDSigSb: sbXml]; if (success != YES) { NSLog(@"%@",gen.LastErrorText); return; } // ----------------------------------------------- // Change the XML declarator to indicate iso-8859-1 (because we'll be saving using iso-8859-1) numReplaced = [[sbXml Replace: @"encoding=\"utf-8\"?>" replacement: @"encoding=\"iso-8859-1\"?>"] intValue]; // Save the signed XML to a file. success = [sbXml WriteFile: @"qa_data/xml_dsig/sii_cl/signed2.xml" charset: @"iso-8859-1" emitBom: NO]; NSLog(@"%@",[sbXml GetAsString]); |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.