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
(PureBasic) IPS MX Signature - Digitally Sign MX DocumentSee more XML Digital Signatures ExamplesDemonstrates how to digitally sign ISO 20022 SWIFT MX messages. Note: This example requires Chilkat v9.5.0.89 or later. Additional internal functionality was added to auto-recognize SWIFT MX messages and do what is appropriate to satisfy the SWIFT MX specifications.
IncludeFile "CkPublicKey.pb" IncludeFile "CkXml.pb" IncludeFile "CkXmlDSig.pb" IncludeFile "CkXmlDSigGen.pb" IncludeFile "CkStringBuilder.pb" IncludeFile "CkCert.pb" Procedure ChilkatExample() ; This example assumes the Chilkat API to have been previously unlocked. ; See Global Unlock Sample for sample code. success.i = 1 ; First create the XML to be signed, or load it from a file, or a string, ; To load XML from a file: xmlToSign.i = CkXml::ckCreate() If xmlToSign.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkXml::ckLoadXmlFile(xmlToSign,"c:/someDir/mx_document.xml") ; Or to load XML from a string success = CkXml::ckLoadXml(xmlToSign,"...") ; Or create the XML directly. CkXml::ckClear(xmlToSign) ; Use this online tool to generate code from sample XML: ; Generate Code to Create XML CkXml::setCkTag(xmlToSign, "DataPDU") CkXml::ckAddAttribute(xmlToSign,"xmlns","urn:cma:stp:xsd:stp.1.0") CkXml::ckUpdateAttrAt(xmlToSign,"Body|AppHdr",1,"xmlns","urn:iso:std:iso:20022:tech:xsd:head.001.001.01") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|Fr|FIId|FinInstnId|BICFI","ZZZZZZZZ") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|To|FIId|FinInstnId|BICFI","YYYYYYYYYY") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|BizMsgIdr","ZZZZZZZZAXXX999999999999999999999") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|MsgDefIdr","pacs.008.001.08") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|BizSvc","IPS") CkXml::ckUpdateChildContent(xmlToSign,"Body|AppHdr|CreDt","2017-09-13T18:18:00Z") CkXml::ckUpdateAttrAt(xmlToSign,"Body|Document",1,"xmlns","urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|GrpHdr|MsgId","ZZZZZZZZAXXX999999999999999999999") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|GrpHdr|CreDtTm","2017-09-13T18:18:00") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|GrpHdr|NbOfTxs","1") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|GrpHdr|SttlmInf|SttlmMtd","CLRG") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|PmtId|EndToEndId","NOTPROVIDED") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|PmtId|TxId","ZZZZZZZZAXXX999999999999999999999") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|PmtTpInf|ClrChanl","RTNS") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|PmtTpInf|LclInstrm|Prtry","CSCT") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|PmtTpInf|CtgyPurp|Prtry","001") CkXml::ckUpdateAttrAt(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|IntrBkSttlmAmt",1,"Ccy","JOD") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|IntrBkSttlmAmt","71.12") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|IntrBkSttlmDt","2018-01-14") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|ChrgBr","SLEV") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|InstgAgt|FinInstnId|BICFI","ZZZZZZZZ") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|InstdAgt|FinInstnId|BICFI","UBSIJOA0") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|Dbtr|Nm","John Johnson") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|DbtrAcct|Id|IBAN","JO22CITI00000000000555555555") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|DbtrAgt|FinInstnId|BICFI","ZZZZZZZZ") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|DbtrAgt|FinInstnId|Othr|Id","200004") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|DbtrAgt|FinInstnId|Othr|SchmeNm|Prtry","1700099999") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|DbtrAgtAcct|Id|IBAN","JO66CITI22222222222222222222") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|CdtrAgt|FinInstnId|BICFI","UBSIJOA0") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|CdtrAgt|FinInstnId|Othr|Id","210027") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|CdtrAgt|FinInstnId|Othr|SchmeNm|Prtry","1400199999") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|CdtrAgtAcct|Id|IBAN","JO44UBSI33333333333333333333") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|Cdtr|Nm","Omega Jones") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|CdtrAcct|Id|IBAN","JO95UBSI00000000000777777777") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|InstrForNxtAgt|InstrInf","/BNF/Details") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|Purp|Prtry","5814") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|RgltryRptg|Dtls|Inf","SOMEINFORMATIONABOUTPAYMENT-1") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|RgltryRptg|Dtls|Inf[1]","SOMEINFORMATIONABOUTPAYMENT-2") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|RgltryRptg|Dtls|Inf[2]","SOMEINFORMATIONABOUTPAYMENT-3") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|Tax|Cdtr|TaxId","9900083901") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|Tax|Dbtr|TaxId","1000387561") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|RmtInf|Ustrd","EDV UCUN ODENIR") CkXml::ckUpdateChildContent(xmlToSign,"Body|Document|FIToFICstmrCdtTrf|CdtTrfTxInf|RmtInf|Ustrd[1]","EXTRA INFO") ; The following XML is to be signed: ; <?xml version="1.0" encoding="UTF-8"?> ; <DataPDU xmlns="urn:cma:stp:xsd:stp.1.0"> ; <Body> ; <AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01"> ; <Fr> ; <FIId> ; <FinInstnId> ; <BICFI>ZZZZZZZZ</BICFI> ; </FinInstnId> ; </FIId> ; </Fr> ; <To> ; <FIId> ; <FinInstnId> ; <BICFI>YYYYYYYYYY</BICFI> ; </FinInstnId> ; </FIId> ; </To> ; <BizMsgIdr>ZZZZZZZZAXXX999999999999999999999</BizMsgIdr> ; <MsgDefIdr>pacs.008.001.08</MsgDefIdr> ; <BizSvc>IPS</BizSvc> ; <CreDt>2017-09-13T18:18:00Z</CreDt> ; </AppHdr> ; <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08"> ; <FIToFICstmrCdtTrf> ; <GrpHdr> ; <MsgId>ZZZZZZZZAXXX999999999999999999999</MsgId> ; <CreDtTm>2017-09-13T18:18:00</CreDtTm> ; <NbOfTxs>1</NbOfTxs> ; <SttlmInf> ; <SttlmMtd>CLRG</SttlmMtd> ; </SttlmInf> ; </GrpHdr> ; <CdtTrfTxInf> ; <PmtId> ; <EndToEndId>NOTPROVIDED</EndToEndId> ; <TxId>ZZZZZZZZAXXX999999999999999999999</TxId> ; </PmtId> ; <PmtTpInf> ; <ClrChanl>RTNS</ClrChanl> ; <LclInstrm> ; <Prtry>CSCT</Prtry> ; </LclInstrm> ; <CtgyPurp> ; <Prtry>001</Prtry> ; </CtgyPurp> ; </PmtTpInf> ; <IntrBkSttlmAmt Ccy="JOD">71.12</IntrBkSttlmAmt> ; <IntrBkSttlmDt>2018-01-14</IntrBkSttlmDt> ; <ChrgBr>SLEV</ChrgBr> ; <InstgAgt> ; <FinInstnId> ; <BICFI>ZZZZZZZZ</BICFI> ; </FinInstnId> ; </InstgAgt> ; <InstdAgt> ; <FinInstnId> ; <BICFI>UBSIJOA0</BICFI> ; </FinInstnId> ; </InstdAgt> ; <Dbtr> ; <Nm>John Johnson</Nm> ; </Dbtr> ; <DbtrAcct> ; <Id> ; <IBAN>JO22CITI00000000000555555555</IBAN> ; </Id> ; </DbtrAcct> ; <DbtrAgt> ; <FinInstnId> ; <BICFI>ZZZZZZZZ</BICFI> ; <Othr> ; <Id>200004</Id> ; <SchmeNm> ; <Prtry>1700089999</Prtry> ; </SchmeNm> ; </Othr> ; </FinInstnId> ; </DbtrAgt> ; <DbtrAgtAcct> ; <Id> ; <IBAN>JO66CITI22222222222222222222</IBAN> ; </Id> ; </DbtrAgtAcct> ; <CdtrAgt> ; <FinInstnId> ; <BICFI>UBSIJOA0</BICFI> ; <Othr> ; <Id>210027</Id> ; <SchmeNm> ; <Prtry>1400199999</Prtry> ; </SchmeNm> ; </Othr> ; </FinInstnId> ; </CdtrAgt> ; <CdtrAgtAcct> ; <Id> ; <IBAN>JO44UBSI33333333333333333333</IBAN> ; </Id> ; </CdtrAgtAcct> ; <Cdtr> ; <Nm>Omega Jones</Nm> ; </Cdtr> ; <CdtrAcct> ; <Id> ; <IBAN>JO95UBSI00000000000777777777</IBAN> ; </Id> ; </CdtrAcct> ; <InstrForNxtAgt> ; <InstrInf>/BNF/Details</InstrInf> ; </InstrForNxtAgt> ; <Purp> ; <Prtry>5814</Prtry> ; </Purp> ; <RgltryRptg> ; <Dtls> ; <Inf>SOMEINFORMATIONABOUTPAYMENT-1</Inf> ; <Inf>SOMEINFORMATIONABOUTPAYMENT-2</Inf> ; <Inf>SOMEINFORMATIONABOUTPAYMENT-3</Inf> ; </Dtls> ; </RgltryRptg> ; <Tax> ; <Cdtr> ; <TaxId>9900083901</TaxId> ; </Cdtr> ; <Dbtr> ; <TaxId>1000387561</TaxId> ; </Dbtr> ; </Tax> ; <RmtInf> ; <Ustrd>EDV UCUN ODENIR</Ustrd> ; <Ustrd>EXTRA INFO</Ustrd> ; </RmtInf> ; </CdtTrfTxInf> ; </FIToFICstmrCdtTrf> ; </Document> ; </Body> ; </DataPDU> gen.i = CkXmlDSigGen::ckCreate() If gen.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXmlDSigGen::setCkSigLocation(gen, "DataPDU|Body|AppHdr|Sgntr") CkXmlDSigGen::setCkSigLocationMod(gen, 0) CkXmlDSigGen::setCkSigNamespacePrefix(gen, "ds") CkXmlDSigGen::setCkSigNamespaceUri(gen, "http://www.w3.org/2000/09/xmldsig#") CkXmlDSigGen::setCkSignedInfoCanonAlg(gen, "EXCL_C14N") CkXmlDSigGen::setCkSignedInfoDigestMethod(gen, "sha256") ; Set the KeyInfoId before adding references.. CkXmlDSigGen::setCkKeyInfoId(gen, "_f9f2c543-e50a-4a50-bd91-50155d27f7e2") ; Create an Object to be added to the Signature. object1.i = CkXml::ckCreate() If object1.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::setCkTag(object1, "xades:QualifyingProperties") CkXml::ckAddAttribute(object1,"xmlns:xades","http://uri.etsi.org/01903/v1.3.2#") CkXml::ckUpdateAttrAt(object1,"xades:SignedProperties",1,"Id","_4ed8e0ed-f47c-4262-909b-0458532ce7aa-signedprops") CkXml::ckUpdateChildContent(object1,"xades:SignedProperties|xades:SignedSignatureProperties|xades:SigningTime","TO BE GENERATED BY CHILKAT") CkXmlDSigGen::ckAddObject(gen,"",CkXml::ckGetXml(object1),"","") ; -------- Reference 1 -------- CkXmlDSigGen::ckAddSameDocRef(gen,"_f9f2c543-e50a-4a50-bd91-50155d27f7e2","sha256","EXCL_C14N","","") ; -------- Reference 2 -------- CkXmlDSigGen::ckAddObjectRef(gen,"_4ed8e0ed-f47c-4262-909b-0458532ce7aa-signedprops","sha256","EXCL_C14N","","http://uri.etsi.org/01903/v1.3.2#SignedProperties") ; -------- Reference 3 -------- CkXmlDSigGen::ckAddSameDocRef(gen,"","sha256","EXCL_C14N","","") ; Provide a certificate + private key. (PFX password is test123) cert.i = CkCert::ckCreate() If cert.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkCert::ckLoadPfxFile(cert,"qa_data/pfx/cert_test123.pfx","test123") If success <> 1 Debug CkCert::ckLastErrorText(cert) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) ProcedureReturn EndIf CkXmlDSigGen::ckSetX509Cert(gen,cert,1) CkXmlDSigGen::setCkKeyInfoType(gen, "X509Data") CkXmlDSigGen::setCkX509Type(gen, "IssuerSerial") ; Load XML to be signed... sbXml.i = CkStringBuilder::ckCreate() If sbXml.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::ckGetXmlSb(xmlToSign,sbXml) ; Can alternatively use "CompactSignedXml" CkXmlDSigGen::setCkBehaviors(gen, "IndentedSignature,LocalSigningTime") ; Sign the XML... success = CkXmlDSigGen::ckCreateXmlDSigSb(gen,sbXml) If success <> 1 Debug CkXmlDSigGen::ckLastErrorText(gen) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) ProcedureReturn EndIf ; ----------------------------------------------- ; Save the signed XML to a file. success = CkStringBuilder::ckWriteFile(sbXml,"qa_output/mx_signed.xml","utf-8",0) Debug CkStringBuilder::ckGetAsString(sbXml) ; ---------------------------------------- ; Verify the signatures we just produced... verifier.i = CkXmlDSig::ckCreate() If verifier.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkXmlDSig::ckLoadSignatureSb(verifier,sbXml) If success <> 1 Debug CkXmlDSig::ckLastErrorText(verifier) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkXmlDSig::ckDispose(verifier) ProcedureReturn EndIf ; Important: The above signature did not include the full X.509 certificate. ; You must call verifier.SetPublicKey to provide the public key of the certificate required for validation. verifyCert.i = CkCert::ckCreate() If verifyCert.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkCert::ckLoadFromFile(verifyCert,"qa_data/certs/cert_test123.cer") If success <> 1 Debug CkCert::ckLastErrorText(verifyCert) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkXmlDSig::ckDispose(verifier) CkCert::ckDispose(verifyCert) ProcedureReturn EndIf pubKey.i = CkCert::ckExportPublicKey(verifyCert) CkXmlDSig::ckSetPublicKey(verifier,pubKey) CkPublicKey::ckDispose(pubKey) numSigs.i = CkXmlDSig::ckNumSignatures(verifier) verifyIdx.i = 0 While verifyIdx < numSigs CkXmlDSig::setCkSelector(verifier, verifyIdx) verified.i = CkXmlDSig::ckVerifySignature(verifier,1) If verified <> 1 Debug CkXmlDSig::ckLastErrorText(verifier) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkXmlDSig::ckDispose(verifier) CkCert::ckDispose(verifyCert) ProcedureReturn EndIf verifyIdx = verifyIdx + 1 Wend Debug "All signatures were successfully verified." CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkXml::ckDispose(object1) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkXmlDSig::ckDispose(verifier) CkCert::ckDispose(verifyCert) ProcedureReturn EndProcedure |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.