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

Aadhaar Paperless Offline e-kyc

See more XML Digital Signatures Examples

Opens an encrypted .zip containing Aadhaar Paperless Offline e-KYC XML. Gets the XML and validates the digital signature. Then computes the hash for the mobile number and Email ID.

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.XmlDSig,
  Chilkat.Zip,
  Chilkat.PublicKey,
  Chilkat.BinData,
  Chilkat.ZipEntry,
  Chilkat.Cert,
  Chilkat.Crypt2,
  Chilkat.Xml;

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

procedure RunDemo;
var
  success: Boolean;
  zip: TZip;
  entry: TZipEntry;
  sharePhrase: string;
  bdXml: TBinData;
  dsig: TXmlDSig;
  cert: TCert;
  pubKey: TPublicKey;
  bVerifyReferenceDigests: Boolean;
  bVerified: Boolean;
  crypt: TCrypt2;
  strToHash: string;
  bdHash: TBinData;
  numTimesToHash: Integer;
  i: Integer;
  tmpStr: string;
  xml: TXml;
  m_hash: string;
  tmpStr: string;
  e_hash: string;

begin
  success := False;

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

  //  Open the .zip containing the Aadhaar Paperless Offline e-KYC XML.
  //  The .zip is encrypted using the "Share Phrase".
  zip := TZip.Create;
  success := zip.OpenZip('qa_data/xml_dsig/offline_paperless_kyc.zip');
  if (success = False) then
    begin
      WriteLn(zip.LastErrorText);
      Exit;
    end;

  //  The .zip should contain 1 XML file.
  entry := TZipEntry.Create;
  success := zip.EntryAt(0,entry);
  if (success = False) then
    begin
      WriteLn(zip.LastErrorText);
      Exit;
    end;

  //  To get the contents, we need to specify the Share Phrase.
  sharePhrase := 'Lock@487';
  zip.DecryptPassword := sharePhrase;

  bdXml := TBinData.Create;
  //  The XML file will be unzipped into the bdXml object.
  success := entry.UnzipToBd(bdXml);
  if (success = False) then
    begin
      WriteLn(entry.LastErrorText);
      Exit;
    end;

  //  First verify the XML digital signature.
  dsig := TXmlDSig.Create;
  success := dsig.LoadSignatureBd(bdXml);
  if (success = False) then
    begin
      WriteLn(dsig.LastErrorText);
      Exit;
    end;

  //  The UIDAI XML signature does not contain the KeyInfo, so we must load the uidai certificate
  //  and indicate that its public key is to be used for verifying the signature.
  cert := TCert.Create;
  success := cert.LoadFromFile('qa_data/xml_dsig/uidai_auth_sign_prod_2023.cer');
  if (success = False) then
    begin
      WriteLn(cert.LastErrorText);
      Exit;
    end;

  //  Get the certificate's public key.
  pubKey := TPublicKey.Create;
  cert.GetPublicKey(pubKey);

  dsig.SetPublicKey(pubKey);

  //  The XML in this example contains only 1 signature.
  bVerifyReferenceDigests := True;
  bVerified := dsig.VerifySignature(bVerifyReferenceDigests);
  if (bVerified = False) then
    begin
      WriteLn(dsig.LastErrorText);
      WriteLn('The signature was not valid.');
      Exit;
    end;

  WriteLn('The XML digital signature is valid.');

  //  Let's compute the hash for the Mobile Number.

  //  	Hashing logic for Mobile Number :
  //  	Sha256(Sha256(Mobile+SharePhrase))*number of times last digit of Aadhaar number
  //  	(Ref ID field contains last 4 digits).
  //  
  //  	Example :
  //  	Mobile: 1234567890
  //  	Aadhaar Number:XXXX XXXX 3632
  //  	Passcode : Lock@487
  //  	Hash: Sha256(Sha256(1234567890Lock@487))*2
  //  	In case of Aadhaar number ends with Zero we will hashed one time.

  crypt := TCrypt2.Create;
  crypt.HashAlgorithm := 'sha256';
  crypt.EncodingMode := 'hexlower';

  strToHash := '1234567890Lock@487';
  bdHash := TBinData.Create;
  success := bdHash.AppendString(strToHash,'utf-8');

  //  Hash a number of times equal to the last digit of your Aadhaar number.
  //  If the Aadhaar number ends with 0, then hash one time.
  //  For this example, we'll just set the number of times to hash
  //  for the case where an Aadhaar number ends in "9"
  numTimesToHash := 9;

  for i := 1 to numTimesToHash do
    begin
      tmpStr := crypt.HashBdENC(bdHash);
      bdHash.Clear();
      bdHash.AppendString(tmpStr,'utf-8');
    end;

  WriteLn('Computed Mobile hash = ' + bdHash.GetString('utf-8'));

  //  Let's get the mobile hash stored in the XML and compare it with our computed hash.
  xml := TXml.Create;
  success := xml.LoadBd(bdXml,True);
  m_hash := xml.ChilkatPath('UidData|Poi|(m)');

  WriteLn('Stored Mobile hash   = ' + m_hash);

  //  Now do the same thing for the email hash:

  strToHash := 'abc@gm.comLock@487';
  bdHash.Clear();
  success := bdHash.AppendString(strToHash,'utf-8');

  for i := 1 to numTimesToHash do
    begin
      tmpStr := crypt.HashBdENC(bdHash);
      bdHash.Clear();
      bdHash.AppendString(tmpStr,'utf-8');
    end;

  WriteLn('Computed Email hash = ' + bdHash.GetString('utf-8'));

  e_hash := xml.ChilkatPath('UidData|Poi|(e)');
  WriteLn('Stored Email hash   = ' + e_hash);


  zip.Free;
  entry.Free;
  bdXml.Free;
  dsig.Free;
  cert.Free;
  pubKey.Free;
  crypt.Free;
  bdHash.Free;
  xml.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.