Sample code for 30+ languages & platforms
Delphi DLL Requires Chilkat v11.0.0+

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 Delphi DLL Downloads

Delphi DLL
var
success: Boolean;
zip: HCkZip;
entry: HCkZipEntry;
sharePhrase: PWideChar;
bdXml: HCkBinData;
dsig: HCkXmlDSig;
cert: HCkCert;
pubKey: HCkPublicKey;
bVerifyReferenceDigests: Boolean;
bVerified: Boolean;
crypt: HCkCrypt2;
strToHash: PWideChar;
bdHash: HCkBinData;
numTimesToHash: Integer;
i: Integer;
tmpStr: PWideChar;
xml: HCkXml;
m_hash: PWideChar;
tmpStr: PWideChar;
e_hash: PWideChar;

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 := CkZip_Create();
success := CkZip_OpenZip(zip,'qa_data/xml_dsig/offline_paperless_kyc.zip');
if (success = False) then
  begin
    Memo1.Lines.Add(CkZip__lastErrorText(zip));
    Exit;
  end;

//  The .zip should contain 1 XML file.
entry := CkZipEntry_Create();
success := CkZip_EntryAt(zip,0,entry);
if (success = False) then
  begin
    Memo1.Lines.Add(CkZip__lastErrorText(zip));
    Exit;
  end;

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

bdXml := CkBinData_Create();
//  The XML file will be unzipped into the bdXml object.
success := CkZipEntry_UnzipToBd(entry,bdXml);
if (success = False) then
  begin
    Memo1.Lines.Add(CkZipEntry__lastErrorText(entry));
    Exit;
  end;

//  First verify the XML digital signature.
dsig := CkXmlDSig_Create();
success := CkXmlDSig_LoadSignatureBd(dsig,bdXml);
if (success = False) then
  begin
    Memo1.Lines.Add(CkXmlDSig__lastErrorText(dsig));
    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 := CkCert_Create();
success := CkCert_LoadFromFile(cert,'qa_data/xml_dsig/uidai_auth_sign_prod_2023.cer');
if (success = False) then
  begin
    Memo1.Lines.Add(CkCert__lastErrorText(cert));
    Exit;
  end;

//  Get the certificate's public key.
pubKey := CkPublicKey_Create();
CkCert_GetPublicKey(cert,pubKey);

CkXmlDSig_SetPublicKey(dsig,pubKey);

//  The XML in this example contains only 1 signature.
bVerifyReferenceDigests := True;
bVerified := CkXmlDSig_VerifySignature(dsig,bVerifyReferenceDigests);
if (bVerified = False) then
  begin
    Memo1.Lines.Add(CkXmlDSig__lastErrorText(dsig));
    Memo1.Lines.Add('The signature was not valid.');
    Exit;
  end;

Memo1.Lines.Add('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 := CkCrypt2_Create();
CkCrypt2_putHashAlgorithm(crypt,'sha256');
CkCrypt2_putEncodingMode(crypt,'hexlower');

strToHash := '1234567890Lock@487';
bdHash := CkBinData_Create();
success := CkBinData_AppendString(bdHash,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 := CkCrypt2__hashBdENC(crypt,bdHash);
    CkBinData_Clear(bdHash);
    CkBinData_AppendString(bdHash,tmpStr,'utf-8');
  end;

Memo1.Lines.Add('Computed Mobile hash = ' + CkBinData__getString(bdHash,'utf-8'));

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

Memo1.Lines.Add('Stored Mobile hash   = ' + m_hash);

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

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

for i := 1 to numTimesToHash do
  begin
    tmpStr := CkCrypt2__hashBdENC(crypt,bdHash);
    CkBinData_Clear(bdHash);
    CkBinData_AppendString(bdHash,tmpStr,'utf-8');
  end;

Memo1.Lines.Add('Computed Email hash = ' + CkBinData__getString(bdHash,'utf-8'));

e_hash := CkXml__chilkatPath(xml,'UidData|Poi|(e)');
Memo1.Lines.Add('Stored Email hash   = ' + e_hash);

CkZip_Dispose(zip);
CkZipEntry_Dispose(entry);
CkBinData_Dispose(bdXml);
CkXmlDSig_Dispose(dsig);
CkCert_Dispose(cert);
CkPublicKey_Dispose(pubKey);
CkCrypt2_Dispose(crypt);
CkBinData_Dispose(bdHash);
CkXml_Dispose(xml);