Sample code for 30+ languages & platforms
Unicode C

Create EBICS Signature (XMLDSIG)

See more EBICS Examples

Demonstrates how to create an EBICS signature. (EBICS is the Electronic Banking Internet Communication Standard)

Chilkat Unicode C Downloads

Unicode C
#include <C_CkStringBuilderW.h>
#include <C_CkXmlDSigGenW.h>
#include <C_CkCertW.h>
#include <C_CkXmlDSigW.h>
#include <C_CkPublicKeyW.h>

void ChilkatSample(void)
    {
    BOOL success;
    HCkStringBuilderW sbXml;
    HCkXmlDSigGenW gen;
    HCkCertW cert;
    HCkXmlDSigW verifier;
    HCkPublicKeyW pubKey;

    success = FALSE;

    //  This example assumes the Chilkat API to have been previously unlocked.
    //  See Global Unlock Sample for sample code.

    //  This is the sample XML to be signed:

    //  <?xml version="1.0" encoding="UTF-8"?>
    //  <ebicsRequest
    //    xmlns="urn:org:ebics:H005"
    //    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    //    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    //    xsi:schemaLocation="urn:org:ebics:H005 ebics_request_H005.xsd"
    //    Version="H005" Revision="1">
    //    <header authenticate="true">
    //      <static>
    //        <HostID>EBIXHOST</HostID>
    //        <Nonce>BDA2312973890654FAC9879A89794E65</Nonce>
    //        <Timestamp>2005-01-30T15:30:45.123Z</Timestamp>
    //        <PartnerID>CUSTM001</PartnerID>
    //        <UserID>USR100</UserID>
    //        <Product Language="en" InstituteID="Institute ID">Product Identifier</Product>
    //        <OrderDetails>
    //          <AdminOrderType>BTU</AdminOrderType>
    //          <BTUOrderParams>
    //            <Service>
    //              <ServiceName>SCT</ServiceName>
    //              <MsgName>pain.001</MsgName>
    //            </Service>
    //          </BTUOrderParams>
    //        </OrderDetails>
    //        <BankPubKeyDigests>
    //          <Authentication Version="X002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">1H/rQr2Axe9hYTV2n/tCp+3UIQQ=</Authentication>
    //          <Encryption Version="E002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">2lwiueWOIER823jSoiOkjl+woeI=</Encryption>
    //        </BankPubKeyDigests>
    //        <SecurityMedium>0000</SecurityMedium>
    //        <NumSegments>2</NumSegments>
    //      </static>
    //      <mutable>
    //        <TransactionPhase>Initialisation</TransactionPhase>
    //      </mutable>
    //    </header>
    //    <body>
    //      <PreValidation authenticate="true">
    //        <DataDigest SignatureVersion="A006"> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</DataDigest>
    //      </PreValidation>
    //      <DataTransfer>
    //        <DataEncryptionInfo authenticate="true">
    //          <EncryptionPubKeyDigest Version="E002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">..here hash value of the public bank key for encryption..</EncryptionPubKeyDigest>
    //          <TransactionKey>EIGI4En6KEB6ArEzw+iq4N1wm6EptcyxXxStA...</TransactionKey>
    //          <HostID>EBIXHOST</HostID>
    //        </DataEncryptionInfo>
    //        <SignatureData authenticate="true">n6KEB6ArEzw+iq4N1wm6EptcyxXxStAO...</SignatureData>
    //        <DataDigest SignatureVersion="A006"> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</DataDigest>
    //      </DataTransfer>
    //    </body>
    //  </ebicsRequest>

    //  Load the above XML from a file.
    sbXml = CkStringBuilderW_Create();
    success = CkStringBuilderW_LoadFile(sbXml,L"qa_data/xml_dsig/ebics/fileToSign.xml",L"utf-8");
    if (success == FALSE) {
        wprintf(L"Failed to load XML input file.\n");
        CkStringBuilderW_Dispose(sbXml);
        return;
    }

    gen = CkXmlDSigGenW_Create();

    //  We're going to insert the signature between the </header> and the <body>
    CkXmlDSigGenW_putSigLocation(gen,L"ebicsRequest|header");

    //  Set the SigLocationMod = 1 to insert *after* the SigLocation
    CkXmlDSigGenW_putSigLocationMod(gen,1);

    //  We wish to use "ds" for the namespace..
    CkXmlDSigGenW_putSigNamespacePrefix(gen,L"ds");
    CkXmlDSigGenW_putSigNamespaceUri(gen,L"http://www.w3.org/2000/09/xmldsig#");

    //  Specify canonicalization and hash algorithms
    CkXmlDSigGenW_putSignedInfoCanonAlg(gen,L"C14N");
    CkXmlDSigGenW_putSignedInfoDigestMethod(gen,L"sha256");

    //  Add the reference.
    //  For EBICS signatures, we pass the special keyword "EBICS" in the 1st argument.
    //  This tells Chilkat to create the reference using URI="#xpointer(//*[@authenticate='true'])"
    CkXmlDSigGenW_AddSameDocRef(gen,L"EBICS",L"sha256",L"C14N",L"",L"");

    //  Provide our certificate + private key. (PFX password is test123)
    //  (You'll use your own certificate, which can be loaded from many different sources by Chilkat, including smart cards.)
    cert = CkCertW_Create();
    success = CkCertW_LoadPfxFile(cert,L"qa_data/pfx/cert_test123.pfx",L"test123");
    if (success == FALSE) {
        wprintf(L"%s\n",CkCertW_lastErrorText(cert));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        return;
    }

    success = CkXmlDSigGenW_SetX509Cert(gen,cert,TRUE);
    if (success == FALSE) {
        wprintf(L"%s\n",CkXmlDSigGenW_lastErrorText(gen));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        return;
    }

    //  We don't want a KeyInfo to be included.
    CkXmlDSigGenW_putKeyInfoType(gen,L"None");

    //  Request an indented signature for readability.
    //  This can be removed after debugging (for a more compact signature).
    CkXmlDSigGenW_putBehaviors(gen,L"IndentedSignature");

    //  Sign the XML.
    success = CkXmlDSigGenW_CreateXmlDSigSb(gen,sbXml);
    if (success == FALSE) {
        wprintf(L"%s\n",CkXmlDSigGenW_lastErrorText(gen));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        return;
    }

    //  This is the XML with the EBICS signature added:

    //  <?xml version="1.0" encoding="UTF-8"?>
    //  <ebicsRequest
    //  xmlns="urn:org:ebics:H005"
    //  xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    //  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    //  xsi:schemaLocation="urn:org:ebics:H005 ebics_request_H005.xsd"
    //  Version="H005" Revision="1">
    //    <header authenticate="true">
    //      <static>
    //        <HostID>EBIXHOST</HostID>
    //        <Nonce>BDA2312973890654FAC9879A89794E65</Nonce>
    //        <Timestamp>2005-01-30T15:30:45.123Z</Timestamp>
    //        <PartnerID>CUSTM001</PartnerID>
    //        <UserID>USR100</UserID>
    //        <Product Language="en" InstituteID="Institute ID">Product Identifier</Product>
    //        <OrderDetails>
    //          <AdminOrderType>BTU</AdminOrderType>
    //          <BTUOrderParams>
    //            <Service>
    //              <ServiceName>SCT</ServiceName>
    //              <MsgName>pain.001</MsgName>
    //            </Service>
    //          </BTUOrderParams>
    //        </OrderDetails>
    //        <BankPubKeyDigests>
    //          <Authentication Version="X002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">1H/rQr2Axe9hYTV2n/tCp+3UIQQ=</Authentication>
    //          <Encryption Version="E002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">2lwiueWOIER823jSoiOkjl+woeI=</Encryption>
    //        </BankPubKeyDigests>
    //        <SecurityMedium>0000</SecurityMedium>
    //        <NumSegments>2</NumSegments>
    //      </static>
    //      <mutable>
    //        <TransactionPhase>Initialisation</TransactionPhase>
    //      </mutable>
    //    </header><AuthSignature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    //    <ds:SignedInfo>
    //      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    //      <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    //      <ds:Reference URI="#xpointer(//*[@authenticate='true'])">
    //        <ds:Transforms>
    //          <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    //        </ds:Transforms>
    //        <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
    //        <ds:DigestValue>jjLD90BedcIVxFENHse6pOnRubVUlHpKjXUF5BUd00k=</ds:DigestValue>
    //      </ds:Reference>
    //    </ds:SignedInfo>
    //    <ds:SignatureValue>TlVgCXGf+3kKZ4LLwqxKoMaDZSBdiDRcGpdKB+tFZ7MZse9jDqtCai7PxcvRLC7yRGRj3XWrAB6IVqXh6tXGqiAtRfa7XjezvJTmUdMEJ3hTEgKqm7cKjjZX5C+lN5XTJghOy0X1bZBl/NBJu/aqY9s8PKsD5Cpm8bFkl2ReBBTCTSF5CRK3XZr+fvWuUX2sFrFS5UDXG8/cmhaKHT15LBOJgYuLYr80dtL251Jy20rIJ5KK8xUz9gpexE61Y/ml6mUPLm8YgdACRdNvCOPRLjCqYwFbnfgaVO6MtSRG819rWyNtBhqVxdzbntiV1UobKbwFiJ1LMMHF0NCo2LGLCw==</ds:SignatureValue>
    //  </AuthSignature>
    //    <body>
    //      <PreValidation authenticate="true">
    //        <DataDigest SignatureVersion="A006"> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</DataDigest>
    //      </PreValidation>
    //      <DataTransfer>
    //        <DataEncryptionInfo authenticate="true">
    //          <EncryptionPubKeyDigest Version="E002" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256">..here hash value of the public bank key for encryption..</EncryptionPubKeyDigest>
    //          <TransactionKey>EIGI4En6KEB6ArEzw+iq4N1wm6EptcyxXxStA...</TransactionKey>
    //          <HostID>EBIXHOST</HostID>
    //        </DataEncryptionInfo>
    //        <SignatureData authenticate="true">n6KEB6ArEzw+iq4N1wm6EptcyxXxStAO...</SignatureData>
    //        <DataDigest SignatureVersion="A006"> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=</DataDigest>
    //      </DataTransfer>
    //    </body>
    //  </ebicsRequest>

    wprintf(L"Here's the EBICS signed XML:\n");
    wprintf(L"%s\n",CkStringBuilderW_getAsString(sbXml));
    wprintf(L"----\n");

    //  Verify the signature we just produced...
    verifier = CkXmlDSigW_Create();
    success = CkXmlDSigW_LoadSignatureSb(verifier,sbXml);
    if (success == FALSE) {
        wprintf(L"%s\n",CkXmlDSigW_lastErrorText(verifier));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        CkXmlDSigW_Dispose(verifier);
        return;
    }

    //  The signature has no KeyInfo, so we must externally provide the key.
    pubKey = CkPublicKeyW_Create();
    CkCertW_GetPublicKey(cert,pubKey);

    success = CkXmlDSigW_SetPublicKey(verifier,pubKey);
    if (success == FALSE) {
        wprintf(L"%s\n",CkXmlDSigW_lastErrorText(verifier));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        CkXmlDSigW_Dispose(verifier);
        CkPublicKeyW_Dispose(pubKey);
        return;
    }

    success = CkXmlDSigW_VerifySignature(verifier,TRUE);
    if (success == FALSE) {
        wprintf(L"%s\n",CkXmlDSigW_lastErrorText(verifier));
        CkStringBuilderW_Dispose(sbXml);
        CkXmlDSigGenW_Dispose(gen);
        CkCertW_Dispose(cert);
        CkXmlDSigW_Dispose(verifier);
        CkPublicKeyW_Dispose(pubKey);
        return;
    }

    wprintf(L"EBICS signature verified.\n");


    CkStringBuilderW_Dispose(sbXml);
    CkXmlDSigGenW_Dispose(gen);
    CkCertW_Dispose(cert);
    CkXmlDSigW_Dispose(verifier);
    CkPublicKeyW_Dispose(pubKey);

    }