Sample code for 30+ languages & platforms
Dart Requires Chilkat v11.0.0+

Create EBICS Signature (XMLDSIG)

See more EBICS Examples

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

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // 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.
  final sbXml = CkStringBuilder();
  try {
    sbXml.loadFile('qa_data/xml_dsig/ebics/fileToSign.xml', 'utf-8');
  } on ChilkatException {
    print('Failed to load XML input file.');
    return;
  }

  final gen = CkXmlDSigGen();

  // We're going to insert the signature between the </header> and the <body>
  gen.sigLocation = 'ebicsRequest|header';

  // Set the SigLocationMod = 1 to insert *after* the SigLocation
  gen.sigLocationMod = 1;

  // We wish to use "ds" for the namespace..
  gen.sigNamespacePrefix = 'ds';
  gen.sigNamespaceUri = 'http://www.w3.org/2000/09/xmldsig#';

  // Specify canonicalization and hash algorithms
  gen.signedInfoCanonAlg = 'C14N';
  gen.signedInfoDigestMethod = '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'])"
  gen.addSameDocRef('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.)
  final cert = CkCert();
  try {
    cert.loadPfxFile('qa_data/pfx/cert_test123.pfx', 'test123');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  try {
    gen.setX509Cert(cert, true);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // We don't want a KeyInfo to be included.
  gen.keyInfoType = 'None';

  // Request an indented signature for readability.
  // This can be removed after debugging (for a more compact signature).
  gen.behaviors = 'IndentedSignature';

  // Sign the XML.
  try {
    gen.createXmlDSigSb(sbXml);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    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>

  print('Here\'s the EBICS signed XML:');
  print(sbXml.getAsString());
  print('----');

  // Verify the signature we just produced...
  final verifier = CkXmlDSig();
  try {
    verifier.loadSignatureSb(sbXml);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

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

  try {
    verifier.setPublicKey(pubKey);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  try {
    verifier.verifySignature(true);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  print('EBICS signature verified.');
}