Sample code for 30+ languages & platforms
C

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 C Downloads

C
#include <C_CkZip.h>
#include <C_CkZipEntry.h>
#include <C_CkBinData.h>
#include <C_CkXmlDSig.h>
#include <C_CkCert.h>
#include <C_CkPublicKey.h>
#include <C_CkCrypt2.h>
#include <C_CkXml.h>

void ChilkatSample(void)
    {
    BOOL success;
    HCkZip zip;
    HCkZipEntry entry;
    const char *sharePhrase;
    HCkBinData bdXml;
    HCkXmlDSig dsig;
    HCkCert cert;
    HCkPublicKey pubKey;
    BOOL bVerifyReferenceDigests;
    BOOL bVerified;
    HCkCrypt2 crypt;
    const char *strToHash;
    HCkBinData bdHash;
    int numTimesToHash;
    int i;
    const char *tmpStr;
    HCkXml xml;
    const char *m_hash;
    const char *tmpStr;
    const char *e_hash;

    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) {
        printf("%s\n",CkZip_lastErrorText(zip));
        CkZip_Dispose(zip);
        return;
    }

    // The .zip should contain 1 XML file.
    entry = CkZipEntry_Create();
    success = CkZip_EntryAt(zip,0,entry);
    if (success == FALSE) {
        printf("%s\n",CkZip_lastErrorText(zip));
        CkZip_Dispose(zip);
        CkZipEntry_Dispose(entry);
        return;
    }

    // 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) {
        printf("%s\n",CkZipEntry_lastErrorText(entry));
        CkZip_Dispose(zip);
        CkZipEntry_Dispose(entry);
        CkBinData_Dispose(bdXml);
        return;
    }

    // First verify the XML digital signature.
    dsig = CkXmlDSig_Create();
    success = CkXmlDSig_LoadSignatureBd(dsig,bdXml);
    if (success == FALSE) {
        printf("%s\n",CkXmlDSig_lastErrorText(dsig));
        CkZip_Dispose(zip);
        CkZipEntry_Dispose(entry);
        CkBinData_Dispose(bdXml);
        CkXmlDSig_Dispose(dsig);
        return;
    }

    // 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) {
        printf("%s\n",CkCert_lastErrorText(cert));
        CkZip_Dispose(zip);
        CkZipEntry_Dispose(entry);
        CkBinData_Dispose(bdXml);
        CkXmlDSig_Dispose(dsig);
        CkCert_Dispose(cert);
        return;
    }

    // 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) {
        printf("%s\n",CkXmlDSig_lastErrorText(dsig));
        printf("The signature was not valid.\n");
        CkZip_Dispose(zip);
        CkZipEntry_Dispose(entry);
        CkBinData_Dispose(bdXml);
        CkXmlDSig_Dispose(dsig);
        CkCert_Dispose(cert);
        CkPublicKey_Dispose(pubKey);
        return;
    }

    printf("The XML digital signature is valid.\n");

    // 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; i <= numTimesToHash; i++) {
        tmpStr = CkCrypt2_hashBdENC(crypt,bdHash);
        CkBinData_Clear(bdHash);
        CkBinData_AppendString(bdHash,tmpStr,"utf-8");
    }

    printf("Computed Mobile hash = %s\n",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)");

    printf("Stored Mobile hash   = %s\n",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; i <= numTimesToHash; i++) {
        tmpStr = CkCrypt2_hashBdENC(crypt,bdHash);
        CkBinData_Clear(bdHash);
        CkBinData_AppendString(bdHash,tmpStr,"utf-8");
    }

    printf("Computed Email hash = %s\n",CkBinData_getString(bdHash,"utf-8"));

    e_hash = CkXml_chilkatPath(xml,"UidData|Poi|(e)");
    printf("Stored Email hash   = %s\n",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);

    }