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) Create XAdES-T Signed XMLSee more XAdES ExamplesThis 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.
#import <CkoXml.h> #import <CkoXmlDSigGen.h> #import <CkoCert.h> #import <CkoJsonObject.h> #import <CkoStringBuilder.h> #import <CkoXmlDSig.h> // This example requires the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. BOOL success = YES; // 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> CkoXml *xmlToSign = [[CkoXml alloc] init]; xmlToSign.Tag = @"es:Dossier"; [xmlToSign AddAttribute: @"xmlns:xsi" value: @"http://www.w3.org/2001/XMLSchema-instance"]; [xmlToSign AddAttribute: @"xmlns:ds" value: @"http://www.w3.org/2000/09/xmldsig#"]; [xmlToSign AddAttribute: @"xmlns" value: @"http://uri.etsi.org/01903/v1.3.2#"]; [xmlToSign AddAttribute: @"xmlns:es" value: @"https://www.microsec.hu/ds/e-szigno30#"]; [xmlToSign AddAttribute: @"xsi:schemaLocation" value: @"https://www.microsec.hu/ds/e-szigno30# https://www.microsec.hu/ds/e-szigno30.xsd"]; [xmlToSign UpdateAttrAt: @"es:DossierProfile" autoCreate: YES attrName: @"Id" attrValue: @"PObject0"]; [xmlToSign UpdateAttrAt: @"es:DossierProfile" autoCreate: YES attrName: @"OBJREF" attrValue: @"Object0"]; [xmlToSign UpdateChildContent: @"es:DossierProfile|es:Title" value: @"e-akta.es3"]; [xmlToSign UpdateChildContent: @"es:DossierProfile|es:E-category" value: @"electronic dossier"]; [xmlToSign UpdateChildContent: @"es:DossierProfile|es:CreationDate" value: @"2022-12-02T07:55:16Z"]; [xmlToSign UpdateAttrAt: @"es:Documents" autoCreate: YES attrName: @"Id" attrValue: @"Object0"]; CkoXmlDSigGen *gen = [[CkoXmlDSigGen alloc] init]; gen.SigLocation = @"es:Dossier"; gen.SigLocationMod = [NSNumber numberWithInt:0]; gen.SigId = @"S9fe8096e-2cac-415d-9222-f6cf2ecb314b"; gen.SigValueId = @"VS9fe8096e-2cac-415d-9222-f6cf2ecb314b"; gen.SignedInfoId = @"SIS9fe8096e-2cac-415d-9222-f6cf2ecb314b"; gen.SignedInfoCanonAlg = @"EXCL_C14N"; gen.SignedInfoDigestMethod = @"sha256"; // Set the KeyInfoId before adding references.. gen.KeyInfoId = @"KS9fe8096e-2cac-415d-9222-f6cf2ecb314b"; // Create an Object to be added to the Signature. CkoXml *object1 = [[CkoXml alloc] init]; object1.Tag = @"es:SignatureProfile"; [object1 AddAttribute: @"Id" value: @"PS9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object1 AddAttribute: @"OBJREF" value: @"Object0"]; [object1 AddAttribute: @"SIGREF" value: @"S9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object1 AddAttribute: @"SIGREFLIST" value: @"#Object0 #PS9fe8096e-2cac-415d-9222-f6cf2ecb314b #PObject0 #XS9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object1 UpdateChildContent: @"es:SignerName" value: @"EC Minsített-Tesztel Péterke"]; [object1 UpdateChildContent: @"es:SDPresented" value: @"false"]; [object1 UpdateChildContent: @"es:Type" value: @"signature"]; [object1 UpdateAttrAt: @"es:Generator|es:Program" autoCreate: YES attrName: @"name" attrValue: @"e-Szigno"]; [object1 UpdateAttrAt: @"es:Generator|es:Program" autoCreate: YES attrName: @"version" attrValue: @"3.3.6.8"]; [object1 UpdateAttrAt: @"es:Generator|es:Device" autoCreate: YES attrName: @"name" attrValue: @"OpenSSL 1.1.1n 15 Mar 2022"]; [object1 UpdateAttrAt: @"es:Generator|es:Device" autoCreate: YES attrName: @"type" attrValue: @""]; [gen AddObject: @"O1S9fe8096e-2cac-415d-9222-f6cf2ecb314b" content: [object1 GetXml] mimeType: @"" encoding: @""]; // Create an Object to be added to the Signature. CkoXml *object2 = [[CkoXml alloc] init]; object2.Tag = @"QualifyingProperties"; [object2 AddAttribute: @"Target" value: @"#S9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object2 AddAttribute: @"Id" value: @"QPS9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object2 UpdateAttrAt: @"SignedProperties" autoCreate: YES attrName: @"Id" attrValue: @"XS9fe8096e-2cac-415d-9222-f6cf2ecb314b"]; [object2 UpdateChildContent: @"SignedProperties|SignedSignatureProperties|SigningTime" value: @"TO BE GENERATED BY CHILKAT"]; [object2 UpdateAttrAt: @"SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|CertDigest|ds:DigestMethod" autoCreate: YES attrName: @"Algorithm" attrValue: @"http://www.w3.org/2001/04/xmlenc#sha256"]; [object2 UpdateChildContent: @"SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|CertDigest|ds:DigestValue" value: @"TO BE GENERATED BY CHILKAT"]; [object2 UpdateChildContent: @"SignedProperties|SignedSignatureProperties|SigningCertificateV2|Cert|IssuerSerialV2" value: @"TO BE GENERATED BY CHILKAT"]; [object2 UpdateChildContent: @"SignedProperties|SignedSignatureProperties|SignaturePolicyIdentifier|SignaturePolicyImplied" value: @""]; [object2 UpdateChildContent: @"SignedProperties|SignedSignatureProperties|SignerRoleV2|ClaimedRoles|ClaimedRole" value: @"tesztel"]; // Here we have the EncapsulatedTimestamp found in the unsigned signature properties. [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp" autoCreate: YES attrName: @"Id" attrValue: @"T72cb4961-4326-4319-857a-7cf55e7ef899"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|ds:CanonicalizationMethod" autoCreate: YES attrName: @"Algorithm" attrValue: @"http://www.w3.org/2001/10/xml-exc-c14n#"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|EncapsulatedTimeStamp" autoCreate: YES attrName: @"Id" attrValue: @"ET72cb4961-4326-4319-857a-7cf55e7ef899"]; [object2 UpdateChildContent: @"UnsignedProperties|UnsignedSignatureProperties|SignatureTimeStamp|EncapsulatedTimeStamp" value: @"TO BE GENERATED BY CHILKAT"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|TimeStampValidationData" autoCreate: YES attrName: @"xmlns" attrValue: @"http://uri.etsi.org/01903/v1.4.1#"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|CertificateValues" autoCreate: YES attrName: @"Id" attrValue: @"CV18c7702d-d45b-44bc-853a-a720f41053cd"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate" autoCreate: YES attrName: @"Id" attrValue: @"EC42db04c8-1422-407b-8c42-189353a55268"]; [object2 UpdateChildContent: @"UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate" value: @"BASE64_CONTENT"]; [object2 UpdateAttrAt: @"UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate[1]" autoCreate: YES attrName: @"Id" attrValue: @"EC04728b44-a32c-46c1-b9bb-85b1f6b3c7d3"]; [object2 UpdateChildContent: @"UnsignedProperties|UnsignedSignatureProperties|CertificateValues|EncapsulatedX509Certificate[1]" value: @"BASE64_CONTENT"]; [gen AddObject: @"O2S9fe8096e-2cac-415d-9222-f6cf2ecb314b" content: [object2 GetXml] mimeType: @"" encoding: @""]; // -------- Reference 1 -------- [gen AddSameDocRef: @"Object0" digestMethod: @"sha256" canonMethod: @"EXCL_C14N" prefixList: @"" refType: @""]; [gen SetRefIdAttr: @"Object0" value: @"Re1f816c4-7898-4544-9b41-f4156dc0c528"]; // -------- Reference 2 -------- [gen AddObjectRef: @"PS9fe8096e-2cac-415d-9222-f6cf2ecb314b" digestMethod: @"sha256" canonMethod: @"EXCL_C14N" prefixList: @"" refType: @""]; [gen SetRefIdAttr: @"PS9fe8096e-2cac-415d-9222-f6cf2ecb314b" value: @"Ra873b616-e568-4c38-ae94-27fbff67cc43"]; // -------- Reference 3 -------- [gen AddSameDocRef: @"PObject0" digestMethod: @"sha256" canonMethod: @"EXCL_C14N" prefixList: @"" refType: @""]; [gen SetRefIdAttr: @"PObject0" value: @"Ra5d85948-5d6a-4914-8c32-242f5d6d9e81"]; // -------- Reference 4 -------- [gen AddObjectRef: @"XS9fe8096e-2cac-415d-9222-f6cf2ecb314b" digestMethod: @"sha256" canonMethod: @"EXCL_C14N" prefixList: @"" refType: @"http://uri.etsi.org/01903#SignedProperties"]; [gen SetRefIdAttr: @"XS9fe8096e-2cac-415d-9222-f6cf2ecb314b" value: @"Ra7412a43-dc05-4e0a-ac84-e9a070214757"]; // Provide a certificate + private key. (PFX password is test123) CkoCert *cert = [[CkoCert alloc] init]; 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"; gen.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: // ------------------------------------------------------------------------------------------- CkoJsonObject *jsonTsa = [[CkoJsonObject alloc] init]; [jsonTsa UpdateString: @"timestampToken.tsaUrl" value: @"http://timestamp.digicert.com"]; [jsonTsa UpdateBool: @"timestampToken.requestTsaCert" value: YES]; [gen SetTsa: jsonTsa]; // Load XML to be signed... CkoStringBuilder *sbXml = [[CkoStringBuilder alloc] init]; [xmlToSign GetXmlSb: sbXml]; gen.Behaviors = @"IndentedSignature,OmitAlreadyDefinedSigNamespace"; // Sign the XML... success = [gen CreateXmlDSigSb: sbXml]; if (success != YES) { NSLog(@"%@",gen.LastErrorText); return; } // ----------------------------------------------- // Save the signed XML to a file. success = [sbXml WriteFile: @"c:/temp/qa_output/signedXml.xml" charset: @"utf-8" emitBom: NO]; NSLog(@"%@",[sbXml GetAsString]); // ---------------------------------------- // Verify the signatures we just produced... CkoXmlDSig *verifier = [[CkoXmlDSig alloc] init]; success = [verifier LoadSignatureSb: sbXml]; if (success != YES) { NSLog(@"%@",verifier.LastErrorText); return; } int numSigs = [verifier.NumSignatures intValue]; int verifyIdx = 0; while (verifyIdx < numSigs) { verifier.Selector = [NSNumber numberWithInt: verifyIdx]; BOOL verified = [verifier VerifySignature: YES]; if (verified != YES) { NSLog(@"%@",verifier.LastErrorText); return; } verifyIdx = verifyIdx + 1; } NSLog(@"%@",@"All signatures were successfully verified."); |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.