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

DSA R,S Signature Values

See more DSA Examples

Creates a DSA signature. Gets r,s values from the signature. Re-creates the DSA signature ASN.1 from the r,s values. Then verifies the signature using the re-created ASN.1 DSA signature.

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.Asn,
  Chilkat.Xml,
  Chilkat.Dsa,
  Chilkat.Crypt2;

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

procedure RunDemo;
var
  success: Boolean;
  crypt: TCrypt2;
  hashStr: string;
  dsa: TDsa;
  pemPrivateKey: string;
  asnSig: string;
  asn: TAsn;
  xml: TXml;
  r: string;
  s: string;
  dsa2: TDsa;
  pemPublicKey: string;

begin
  success := False;

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

  crypt := TCrypt2.Create;

  crypt.EncodingMode := 'hex';
  crypt.HashAlgorithm := 'sha-1';

  hashStr := crypt.HashFileENC('qa_data/hamlet.xml');
  WriteLn('hash to sign: ' + hashStr);

  dsa := TDsa.Create;

  pemPrivateKey := dsa.LoadText('qa_data/dsa/dsaPrivKey2.pem');
  success := dsa.FromPem(pemPrivateKey);
  if (success = False) then
    begin
      WriteLn(dsa.LastErrorText);
      Exit;
    end;

  //  Load the hash to be signed into the DSA object:
  success := dsa.SetEncodedHash('hex',hashStr);
  if (success = False) then
    begin
      WriteLn(dsa.LastErrorText);
      Exit;
    end;

  //  Sign the hash.
  success := dsa.SignHash();
  if (success = False) then
    begin
      WriteLn(dsa.LastErrorText);
      Exit;
    end;

  //  Get the ASN.1 signature.
  asnSig := dsa.GetEncodedSignature('base64');
  WriteLn('Signature: ' + asnSig);

  //  Examine the details of the ASN.1 signature.
  //  We want to get the r,s values as hex strings..
  asn := TAsn.Create;
  success := asn.LoadEncoded(asnSig,'base64');
  if (success = False) then
    begin
      WriteLn(asn.LastErrorText);
      Exit;
    end;

  //  Get the ASN.1 as XML.
  xml := TXml.Create;
  success := xml.LoadXml(asn.AsnToXml());
  WriteLn('Signature as XML: ');
  WriteLn(xml.GetXml());

  //  Sample XML shown here.
  //  The r and s values are the two hex strings in the XML.

  //  <?xml version="1.0" encoding="utf-8"?>
  //  <sequence>
  //      <int>2C187F3AB6E47A66497B86CE97BB39E2133810F5</int>
  //      <int>588E53D3F7B69636B48FD7175E99A3961BD7D775</int>
  //  </sequence>

  //  Pretend we're starting with r,s
  r := '2C187F3AB6E47A66497B86CE97BB39E2133810F5';
  s := '588E53D3F7B69636B48FD7175E99A3961BD7D775';

  //  Build the XML that will be converted to ASN.1
  xml.Clear();
  xml.Tag := 'sequence';
  xml.NewChild2('int',r);
  xml.NewChild2('int',s);

  //  Convert the XML to ASN.1
  success := asn.LoadAsnXml(xml.GetXml());

  //  Emit the signature as DER encoded ASN.1 (base64)
  asnSig := asn.GetEncodedDer('base64');

  //  --------------------------------------------------------------------
  //  Verify the signature using the asnSig we built from the r,s values
  //  --------------------------------------------------------------------

  dsa2 := TDsa.Create;

  //  Load the DSA public key to be used for verification:

  pemPublicKey := dsa2.LoadText('qa_data/dsa/dsaPubKey2.pem');
  success := dsa2.FromPublicPem(pemPublicKey);
  if (success = False) then
    begin
      WriteLn(dsa2.LastErrorText);
      Exit;
    end;

  //  Load the hash to be verified.
  success := dsa2.SetEncodedHash('hex',hashStr);
  if (success = False) then
    begin
      WriteLn(dsa2.LastErrorText);
      Exit;
    end;

  //  Load the ASN.1 signature:
  success := dsa2.SetEncodedSignature('base64',asnSig);
  if (success = False) then
    begin
      WriteLn(dsa2.LastErrorText);
      Exit;
    end;

  //  Verify:
  success := dsa2.Verify();
  if (success = False) then
    begin
      WriteLn(dsa2.LastErrorText);
    end
  else
    begin
      WriteLn('DSA Signature Verified!');
    end;


  crypt.Free;
  dsa.Free;
  asn.Free;
  xml.Free;
  dsa2.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.