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