Pascal (Lazarus/Delphi)
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
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.