PureBasic
PureBasic
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 PureBasic Downloads
IncludeFile "CkPublicKey.pb"
IncludeFile "CkBinData.pb"
IncludeFile "CkXmlDSig.pb"
IncludeFile "CkZipEntry.pb"
IncludeFile "CkXml.pb"
IncludeFile "CkCrypt2.pb"
IncludeFile "CkZip.pb"
IncludeFile "CkCert.pb"
Procedure ChilkatExample()
success.i = 0
; 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.i = CkZip::ckCreate()
If zip.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkZip::ckOpenZip(zip,"qa_data/xml_dsig/offline_paperless_kyc.zip")
If success = 0
Debug CkZip::ckLastErrorText(zip)
CkZip::ckDispose(zip)
ProcedureReturn
EndIf
; The .zip should contain 1 XML file.
entry.i = CkZipEntry::ckCreate()
If entry.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkZip::ckEntryAt(zip,0,entry)
If success = 0
Debug CkZip::ckLastErrorText(zip)
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
ProcedureReturn
EndIf
; To get the contents, we need to specify the Share Phrase.
sharePhrase.s = "Lock@487"
CkZip::setCkDecryptPassword(zip, sharePhrase)
bdXml.i = CkBinData::ckCreate()
If bdXml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; The XML file will be unzipped into the bdXml object.
success = CkZipEntry::ckUnzipToBd(entry,bdXml)
If success = 0
Debug CkZipEntry::ckLastErrorText(entry)
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
CkBinData::ckDispose(bdXml)
ProcedureReturn
EndIf
; First verify the XML digital signature.
dsig.i = CkXmlDSig::ckCreate()
If dsig.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXmlDSig::ckLoadSignatureBd(dsig,bdXml)
If success = 0
Debug CkXmlDSig::ckLastErrorText(dsig)
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
CkBinData::ckDispose(bdXml)
CkXmlDSig::ckDispose(dsig)
ProcedureReturn
EndIf
; 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.i = CkCert::ckCreate()
If cert.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkCert::ckLoadFromFile(cert,"qa_data/xml_dsig/uidai_auth_sign_prod_2023.cer")
If success = 0
Debug CkCert::ckLastErrorText(cert)
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
CkBinData::ckDispose(bdXml)
CkXmlDSig::ckDispose(dsig)
CkCert::ckDispose(cert)
ProcedureReturn
EndIf
; Get the certificate's public key.
pubKey.i = CkPublicKey::ckCreate()
If pubKey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCert::ckGetPublicKey(cert,pubKey)
CkXmlDSig::ckSetPublicKey(dsig,pubKey)
; The XML in this example contains only 1 signature.
bVerifyReferenceDigests.i = 1
bVerified.i = CkXmlDSig::ckVerifySignature(dsig,bVerifyReferenceDigests)
If bVerified = 0
Debug CkXmlDSig::ckLastErrorText(dsig)
Debug "The signature was not valid."
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
CkBinData::ckDispose(bdXml)
CkXmlDSig::ckDispose(dsig)
CkCert::ckDispose(cert)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndIf
Debug "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.i = CkCrypt2::ckCreate()
If crypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCrypt2::setCkHashAlgorithm(crypt, "sha256")
CkCrypt2::setCkEncodingMode(crypt, "hexlower")
strToHash.s = "1234567890Lock@487"
bdHash.i = CkBinData::ckCreate()
If bdHash.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkBinData::ckAppendString(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.i = 9
i.i
For i = 1 To numTimesToHash
tmpStr.s = CkCrypt2::ckHashBdENC(crypt,bdHash)
CkBinData::ckClear(bdHash)
CkBinData::ckAppendString(bdHash,tmpStr,"utf-8")
Next
Debug "Computed Mobile hash = " + CkBinData::ckGetString(bdHash,"utf-8")
; Let's get the mobile hash stored in the XML and compare it with our computed hash.
xml.i = CkXml::ckCreate()
If xml.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkXml::ckLoadBd(xml,bdXml,1)
m_hash.s = CkXml::ckChilkatPath(xml,"UidData|Poi|(m)")
Debug "Stored Mobile hash = " + m_hash
; Now do the same thing for the email hash:
strToHash = "abc@gm.comLock@487"
CkBinData::ckClear(bdHash)
success = CkBinData::ckAppendString(bdHash,strToHash,"utf-8")
For i = 1 To numTimesToHash
tmpStr.s = CkCrypt2::ckHashBdENC(crypt,bdHash)
CkBinData::ckClear(bdHash)
CkBinData::ckAppendString(bdHash,tmpStr,"utf-8")
Next
Debug "Computed Email hash = " + CkBinData::ckGetString(bdHash,"utf-8")
e_hash.s = CkXml::ckChilkatPath(xml,"UidData|Poi|(e)")
Debug "Stored Email hash = " + e_hash
CkZip::ckDispose(zip)
CkZipEntry::ckDispose(entry)
CkBinData::ckDispose(bdXml)
CkXmlDSig::ckDispose(dsig)
CkCert::ckDispose(cert)
CkPublicKey::ckDispose(pubKey)
CkCrypt2::ckDispose(crypt)
CkBinData::ckDispose(bdHash)
CkXml::ckDispose(xml)
ProcedureReturn
EndProcedure