C
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 C Downloads
#include <C_CkStringBuilder.h>
#include <C_CkXmlDSigGen.h>
#include <C_CkCert.h>
#include <C_CkXmlDSig.h>
#include <C_CkPublicKey.h>
void ChilkatSample(void)
{
BOOL success;
HCkStringBuilder sbXml;
HCkXmlDSigGen gen;
HCkCert cert;
HCkXmlDSig verifier;
HCkPublicKey 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 = CkStringBuilder_Create();
success = CkStringBuilder_LoadFile(sbXml,"qa_data/xml_dsig/ebics/fileToSign.xml","utf-8");
if (success == FALSE) {
printf("Failed to load XML input file.\n");
CkStringBuilder_Dispose(sbXml);
return;
}
gen = CkXmlDSigGen_Create();
// We're going to insert the signature between the </header> and the <body>
CkXmlDSigGen_putSigLocation(gen,"ebicsRequest|header");
// Set the SigLocationMod = 1 to insert *after* the SigLocation
CkXmlDSigGen_putSigLocationMod(gen,1);
// We wish to use "ds" for the namespace..
CkXmlDSigGen_putSigNamespacePrefix(gen,"ds");
CkXmlDSigGen_putSigNamespaceUri(gen,"http://www.w3.org/2000/09/xmldsig#");
// Specify canonicalization and hash algorithms
CkXmlDSigGen_putSignedInfoCanonAlg(gen,"C14N");
CkXmlDSigGen_putSignedInfoDigestMethod(gen,"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'])"
CkXmlDSigGen_AddSameDocRef(gen,"EBICS","sha256","C14N","","");
// 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 = CkCert_Create();
success = CkCert_LoadPfxFile(cert,"qa_data/pfx/cert_test123.pfx","test123");
if (success == FALSE) {
printf("%s\n",CkCert_lastErrorText(cert));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
return;
}
success = CkXmlDSigGen_SetX509Cert(gen,cert,TRUE);
if (success == FALSE) {
printf("%s\n",CkXmlDSigGen_lastErrorText(gen));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
return;
}
// We don't want a KeyInfo to be included.
CkXmlDSigGen_putKeyInfoType(gen,"None");
// Request an indented signature for readability.
// This can be removed after debugging (for a more compact signature).
CkXmlDSigGen_putBehaviors(gen,"IndentedSignature");
// Sign the XML.
success = CkXmlDSigGen_CreateXmlDSigSb(gen,sbXml);
if (success == FALSE) {
printf("%s\n",CkXmlDSigGen_lastErrorText(gen));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_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>
printf("Here's the EBICS signed XML:\n");
printf("%s\n",CkStringBuilder_getAsString(sbXml));
printf("----\n");
// Verify the signature we just produced...
verifier = CkXmlDSig_Create();
success = CkXmlDSig_LoadSignatureSb(verifier,sbXml);
if (success == FALSE) {
printf("%s\n",CkXmlDSig_lastErrorText(verifier));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
CkXmlDSig_Dispose(verifier);
return;
}
// The signature has no KeyInfo, so we must externally provide the key.
pubKey = CkPublicKey_Create();
CkCert_GetPublicKey(cert,pubKey);
success = CkXmlDSig_SetPublicKey(verifier,pubKey);
if (success == FALSE) {
printf("%s\n",CkXmlDSig_lastErrorText(verifier));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
CkXmlDSig_Dispose(verifier);
CkPublicKey_Dispose(pubKey);
return;
}
success = CkXmlDSig_VerifySignature(verifier,TRUE);
if (success == FALSE) {
printf("%s\n",CkXmlDSig_lastErrorText(verifier));
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
CkXmlDSig_Dispose(verifier);
CkPublicKey_Dispose(pubKey);
return;
}
printf("EBICS signature verified.\n");
CkStringBuilder_Dispose(sbXml);
CkXmlDSigGen_Dispose(gen);
CkCert_Dispose(cert);
CkXmlDSig_Dispose(verifier);
CkPublicKey_Dispose(pubKey);
}