Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Create EBICS Signature (XMLDSIG)

See more EBICS Examples

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

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.StringBuilder,
  Chilkat.PublicKey,
  Chilkat.XmlDSigGen,
  Chilkat.Cert,
  Chilkat.XmlDSig;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  sbXml: TStringBuilder;
  gen: TXmlDSigGen;
  cert: TCert;
  verifier: TXmlDSig;
  pubKey: TPublicKey;

begin
  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 := TStringBuilder.Create;
  success := sbXml.LoadFile('qa_data/xml_dsig/ebics/fileToSign.xml','utf-8');
  if (success = False) then
    begin
      WriteLn('Failed to load XML input file.');
      Exit;
    end;

  gen := TXmlDSigGen.Create;

  //  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.)
  cert := TCert.Create;
  success := cert.LoadPfxFile('qa_data/pfx/cert_test123.pfx','test123');
  if (success = False) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;

  success := gen.SetX509Cert(cert,True);
  if (success = False) then
    begin
      WriteLn(gen.LastErrorText);
      Exit;
    end;

  //  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.
  success := gen.CreateXmlDSigSb(sbXml);
  if (success = False) then
    begin
      WriteLn(gen.LastErrorText);
      Exit;
    end;

  //  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>

  WriteLn('Here''s the EBICS signed XML:');
  WriteLn(sbXml.GetAsString());
  WriteLn('----');

  //  Verify the signature we just produced...
  verifier := TXmlDSig.Create;
  success := verifier.LoadSignatureSb(sbXml);
  if (success = False) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  //  The signature has no KeyInfo, so we must externally provide the key.
  pubKey := TPublicKey.Create;
  cert.GetPublicKey(pubKey);

  success := verifier.SetPublicKey(pubKey);
  if (success = False) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  success := verifier.VerifySignature(True);
  if (success = False) then
    begin
      WriteLn(verifier.LastErrorText);
      Exit;
    end;

  WriteLn('EBICS signature verified.');


  sbXml.Free;
  gen.Free;
  cert.Free;
  verifier.Free;
  pubKey.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.