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) Create Signed SOAP XML for DIAN Colombia WCF ServiceDemonstrates how to create a signed SOAP XML document for DIAN Colombia.
IncludeFile "CkBinData.pb" IncludeFile "CkXmlDSig.pb" IncludeFile "CkXml.pb" IncludeFile "CkXmlDSigGen.pb" IncludeFile "CkStringBuilder.pb" IncludeFile "CkCert.pb" Procedure ChilkatExample() ; This example requires the Chilkat API to have been previously unlocked. ; See Global Unlock Sample for sample code. ; This example will produce a signed SOAP XML message that looks like this: ; <?xml version="1.0" encoding="utf-8"?> ; <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:wcf="http://wcf.dian.colombia"> ; <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> ; <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> ; <wsu:Timestamp wsu:Id="TS-F25839120CBA3ECDAD68754D0443A667636FDA68"> ; <wsu:Created>2019-08-23T23:03:01Z</wsu:Created> ; <wsu:Expires>2019-08-24T15:43:01Z</wsu:Expires> ; </wsu:Timestamp> ; <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ; ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" ; wsu:Id="ABCXYZ-9F0F7E15A59816E680B4735080A789DC1EED6C9C">MIIG8jCCBd ... zLjGQUB6lcz</wsse:BinarySecurityToken> ; <ds:Signature Id="SIG-F25839120CBA3ECDAD68754D0443A667636FDA68" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ; <ds:SignedInfo> ; <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> ; <ec:InclusiveNamespaces PrefixList="wsa soap wcf" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/> ; </ds:CanonicalizationMethod> ; <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> ; <ds:Reference URI="#ID-F25839120CBA3ECDAD68754D0443A667636FDA68"> ; <ds:Transforms> ; <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"> ; <ec:InclusiveNamespaces PrefixList="soap wcf" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/> ; </ds:Transform> ; </ds:Transforms> ; <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> ; <ds:DigestValue>gSIKtjS/BKA2bgecXkM8lYVBDqlXcU3juNYT9a+bSnM=</ds:DigestValue> ; </ds:Reference> ; </ds:SignedInfo> ; <ds:SignatureValue>sL7rOdyfkEnKgJja0eWrv ... YqG0T0pflBsGW9zXkjQ9NvAw==</ds:SignatureValue> ; <ds:KeyInfo Id="KI-F25839120CBA3ECDAD68754D0443A667636FDA68"> ; <wsse:SecurityTokenReference wsu:Id="STR-F25839120CBA3ECDAD68754D0443A667636FDA68"> ; <wsse:Reference URI="#ABCXYZ-9F0F7E15A59816E680B4735080A789DC1EED6C9C" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/> ; </wsse:SecurityTokenReference> ; </ds:KeyInfo> ; </ds:Signature> ; </wsse:Security> ; <wsa:Action>http://wcf.dian.colombia/IWcfDianCustomerServices/GetStatus</wsa:Action> ; <wsa:To wsu:Id="ID-F25839120CBA3ECDAD68754D0443A667636FDA68" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc</wsa:To> ; </soap:Header> ; <soap:Body> ; <wcf:GetStatus> ; <wcf:trackId>123456666</wcf:trackId> ; </wcf:GetStatus> ; </soap:Body> ; </soap:Envelope> ; Use this online tool to generate code from sample Signed XML: ; Generate Code to Create Signed XML success.i = 1 ; Create the XML to be signed... xmlToSign.i = CkXml::ckCreate() If xmlToSign.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::setCkTag(xmlToSign, "soap:Envelope") CkXml::ckAddAttribute(xmlToSign,"xmlns:soap","http://www.w3.org/2003/05/soap-envelope") CkXml::ckAddAttribute(xmlToSign,"xmlns:wcf","http://wcf.dian.colombia") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header",1,"xmlns:wsa","http://www.w3.org/2005/08/addressing") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security",1,"xmlns:wsse","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security",1,"xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security|wsu:Timestamp",1,"wsu:Id","TS-F25839120CBA3ECDAD68754D0443A667636FDA68") CkXml::ckUpdateChildContent(xmlToSign,"soap:Header|wsse:Security|wsu:Timestamp|wsu:Created","2019-08-23T23:03:01Z") CkXml::ckUpdateChildContent(xmlToSign,"soap:Header|wsse:Security|wsu:Timestamp|wsu:Expires","2019-08-24T15:43:01Z") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security|wsse:BinarySecurityToken",1,"EncodingType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security|wsse:BinarySecurityToken",1,"ValueType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsse:Security|wsse:BinarySecurityToken",1,"wsu:Id","ABCXYZ-9F0F7E15A59816E680B4735080A789DC1EED6C9C") CkXml::ckUpdateChildContent(xmlToSign,"soap:Header|wsse:Security|wsse:BinarySecurityToken","BinarySecurityToken_Base64Binary_Content") CkXml::ckUpdateChildContent(xmlToSign,"soap:Header|wsa:Action","http://wcf.dian.colombia/IWcfDianCustomerServices/GetStatus") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsa:To",1,"wsu:Id","ID-F25839120CBA3ECDAD68754D0443A667636FDA68") CkXml::ckUpdateAttrAt(xmlToSign,"soap:Header|wsa:To",1,"xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd") CkXml::ckUpdateChildContent(xmlToSign,"soap:Header|wsa:To","https://vpfe-hab.dian.gov.co/WcfDianCustomerServices.svc") CkXml::ckUpdateChildContent(xmlToSign,"soap:Body|wcf:GetStatus|wcf:trackId","123456666") gen.i = CkXmlDSigGen::ckCreate() If gen.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXmlDSigGen::setCkSigLocation(gen, "soap:Envelope|soap:Header|wsse:Security") CkXmlDSigGen::setCkSigLocationMod(gen, 0) CkXmlDSigGen::setCkSigId(gen, "SIG-F25839120CBA3ECDAD68754D0443A667636FDA68") 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, "KI-F25839120CBA3ECDAD68754D0443A667636FDA68") ; -------- Reference 1 -------- CkXmlDSigGen::ckAddSameDocRef(gen,"ID-F25839120CBA3ECDAD68754D0443A667636FDA68","sha256","EXCL_C14N","soap wcf","") ; 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) CkCert::ckDispose(cert) ProcedureReturn EndIf CkXmlDSigGen::ckSetX509Cert(gen,cert,1) CkXmlDSigGen::setCkKeyInfoType(gen, "Custom") ; Create the custom KeyInfo XML.. xmlCustomKeyInfo.i = CkXml::ckCreate() If xmlCustomKeyInfo.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::setCkTag(xmlCustomKeyInfo, "wsse:SecurityTokenReference") CkXml::ckAddAttribute(xmlCustomKeyInfo,"wsu:Id","STR-F25839120CBA3ECDAD68754D0443A667636FDA68") CkXml::ckUpdateAttrAt(xmlCustomKeyInfo,"wsse:Reference",1,"URI","#ABCXYZ-9F0F7E15A59816E680B4735080A789DC1EED6C9C") CkXml::ckUpdateAttrAt(xmlCustomKeyInfo,"wsse:Reference",1,"ValueType","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3") CkXml::setCkEmitXmlDecl(xmlCustomKeyInfo, 0) CkXmlDSigGen::setCkCustomKeyInfoXml(gen, CkXml::ckGetXml(xmlCustomKeyInfo)) ; Load XML to be signed... sbXml.i = CkStringBuilder::ckCreate() If sbXml.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::ckGetXmlSb(xmlToSign,sbXml) ; Update BinarySecurityToken_Base64Binary_Content with the actual X509 of the signing cert. bdCert.i = CkBinData::ckCreate() If bdCert.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkCert::ckExportCertDerBd(cert,bdCert) nReplaced.i = CkStringBuilder::ckReplace(sbXml,"BinarySecurityToken_Base64Binary_Content",CkBinData::ckGetEncoded(bdCert,"base64")) CkXmlDSigGen::setCkBehaviors(gen, "IndentedSignature") ; Sign the XML... success = CkXmlDSigGen::ckCreateXmlDSigSb(gen,sbXml) If success <> 1 Debug CkXmlDSigGen::ckLastErrorText(gen) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) CkXml::ckDispose(xmlCustomKeyInfo) CkStringBuilder::ckDispose(sbXml) CkBinData::ckDispose(bdCert) ProcedureReturn EndIf ; ----------------------------------------------- ; Save the signed XML to a file. success = CkStringBuilder::ckWriteFile(sbXml,"qa_output/signedXml.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) CkCert::ckDispose(cert) CkXml::ckDispose(xmlCustomKeyInfo) CkStringBuilder::ckDispose(sbXml) CkBinData::ckDispose(bdCert) CkXmlDSig::ckDispose(verifier) ProcedureReturn EndIf 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) CkCert::ckDispose(cert) CkXml::ckDispose(xmlCustomKeyInfo) CkStringBuilder::ckDispose(sbXml) CkBinData::ckDispose(bdCert) CkXmlDSig::ckDispose(verifier) ProcedureReturn EndIf verifyIdx = verifyIdx + 1 Wend Debug "All signatures were successfully verified." ; -------------------------------------------------------------------------------- ; Also see Chilkat's Online WSDL Code Generator ; to generate code and SOAP Request and Response XML for each operation in a WSDL. ; -------------------------------------------------------------------------------- CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) CkXml::ckDispose(xmlCustomKeyInfo) CkStringBuilder::ckDispose(sbXml) CkBinData::ckDispose(bdCert) CkXmlDSig::ckDispose(verifier) ProcedureReturn EndProcedure |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.