One of the best things about Aadhaar API was its ability to allow organisations like Banks and other financial institutions to instantly verify the identity of the customer, as required by RBI regulations. This meant new accounts and loan disbursements could be done almost instantly and with minimum to no human intervention.
With the Supreme court’s verdict private institutions were barred from using Aadhaar APIs in September of 2018. Though with it’s latest ordinance Government of India now has allowed Banks and Telecom companies to use the API’s for user verification. With the APIs being back we thought it was the right time to help your developers understand how they could use the documentation that they got from UIDAI to integrate Aadhaar auth within their apps.
Before we can move forward to the actual process of integration, it is essential that we understand the terms that have been frequently used within documentation.
What is the Aadhaar Platform:
The Aadhaar platform is an initiative by the Government of India which allows private entities to leverage the Aadhaar data stored by UIDAI in CIDR (Central Identities Data Repository) databases. The Aadhar platform exports Aadhaar APIs which are open to developers and can be used for Authentication and eKYC services.
There two main entities involved in usage and distribution of the Aadhar Platform, these are:
- Authentication User Agency (AUA) and Sub-AUA: AUAs are the entities using Aadhaar Authentication as part of their service delivery cycle for customers, beneficiaries, employees. It is the principal entity that sends the authentication request to enable day to day business functions. For examples Government Departments like NSDL, Banks, and other public or private organizations. All AUAs (Authentication User Agencies) must register within the Aadhaar authentication server to perform secure authentication. Sub-AUA is an entity having a business relationship with AUA offering specific services in a particular domain.
- Authentication Service Agency (ASA): The ASAs play the role of ‘enabling intermediaries’ and have an established secure connection with CIDR. I.e. it aims to provide connectivity using a private secure network to UIDAI’s data centers for transmitting authentication requests from various AUAs.
Aadhar Authentication Flow:
The Aadhaar Authentication Flow denotes the flow of requests and responses that takes place during an Authentication request using the Aadhaar API. The stages in the Aadhar Authentication are described below:
Step 1:- The user places an Authentication request through a Hardware device which is capable of capturing Aadhaar Number / Biometric information. The information captured here is encrypted and can only be decrypted by UIDAI
Step 2:- AUA client application sends this data securely to the AUA servers. AUA servers sign the request.
Step 3:- AUA captures data along with necessary additional field which is sent across to the ASA.
Step 4:- The ASA sends the package to UIDAI which queries the CIDR databases to verify if the Aadhaar data requested is valid or not.
Step 5:- The UIDAI sends ‘Yes’ or ‘No’ response or resident details are sent back to the ASA and then to AUA server.
Step 6:- The AUA server confirms receipt of the data
Step 7:- Service delivery is offered to the Aadhaar user based on the authentication.
Aadhaar API
API Format
Following is the API format provided by UIDAI
The Element Details of the API is given below:
- Host – It is an Aadhaar authentication server address. It provides an actual production server address to ASAs. The production servers can only be accessed with a private secure connection. ASA server has to ensure that the actual URL is configurable.
- ver – Its an optional parameter which denotes the version of Authentication API. If ver is not provided, URL will point to current version. UIDAI hosts multiple versions for supporting gradual migration.
- ac – This is a unique code for the AUA which is assigned by UIDAI. Its an alphanumeric string having maximum length 10. (A default value “public” is available for testing.)
- uid[0] and uid[1] – First 2 digits of Aadhaar Number. Used for load-balancing.
- asalk – A valid ASA license key. ASAs must send one of their valid license keys at the end of the URL. It is better to ensure that the license keys are maintained safely. Before adding the license key to the URL, one has to ensure that it is “URL encoded” to handle special characters.
Authentication API: Input Data Format
Aadhaar authentication uses XML as the data format for input and output. Following is the XML data format for authentication API:
“Data” element contains “Pid” (Personal Identity Data) element which is a base-64 encoded encrypted block. Complete “Data” block should be encrypted at the time of capture on the client. When using PID block in XML format (which is the default), following is the format for “Pid” element:
Instead of XML format, this version also allows PID block to be in binary format based on Protocol Buffers standard ((http://code.google.com/p/protobuf/). Notice that “Auth” XML must be in XML format. Binary format is only supported for PID block to enable smaller packet sizes to be transmitted from devices.
Authentication API: Response Data Format:
Authentication API will not provide any identity data as part of the response. It only tries to match the given input and respond with a “yes/no”. Response XML is as follows:
Agencies which use the authentication response requires a mechanism to validate the authentication response for non-repudiation purposes.To enable verification and audit, authentication response has to be digitally signed by UIDAI and the signature would be a part of the response.
Authentication API Auth flow
- Client application/device captures the residents details. It should be encrypted at the time of capture as per UIDAI documentation. The encrypted data is called PID(Person Identification Data) block.
- Client application passes this encrypted data to AUA server which is then signed using Signing Certificate stored in HSM.
- After Singing the Auth request. It is sent to ASA over secured communication channel. ASA then forwards it to UIDAI over leased line or similar secured network.
- Upon receiving the Auth request, UIDAI verifies the ASA and AUA using License keys and digital signatures. If all is good, UIDAI decrypts the PID block to read the residents data and checks it against the CIDR(Central identification Data Repository). If all the given details of resident are correct, UIDAI will send YES or NO response accordingly.
How to integrate Aadhaar Auth API?
To begin integrating Aadhaar Auth API, the first this you would need to do is download the UIDAI integration document from UIDAI website.
Do take your time to read through the document though we have tried to cover most of the important bits in this article..
To begin integration it is paramount that you understand how the information flow w.r.t how Aadhaar Auth works (this is mentioned in the section about Auth flow above)
>>Client application/device captures the residents details. It should be encrypted at the time of capture as per UIDAI documentation. The encrypted data is called PID(Person Identification Data) block.
The client application device is essentially the Iris or fingerprint scanner attached to your system. UIDAI has licensed certain manufacturers to make this device which at the time of purchase needs to be registered with UIDAI before it can be used with Aadhaar API’s.
PID block encryption process is a combination of symmetric(256 bit AES) and Asymmetric encryption (2048 bit RSA) algorithm.
A very good sample of AES encryption can be found at https://howtodoinjava.com/security/java-aes-encryption-example/
Here is the sample code that you can use to create PID’s, do consider the following code is based on developer account and details provided by UIDAI here
function encryptMcrypt($data) { $fp=fopen(UIDAI_PUBLIC_CERTIFICATE,"r"); $pub_key_string=fread($fp,8192); openssl_public_encrypt($data, $encrypted_data, $pub_key_string, OPENSSL_PKCS1_PADDING); return $encrypted_data; } function generateRandomString($length = 32) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } function encryptPID($data,$skey) { $result=openssl_encrypt ( $data , 'AES-256-ECB' , $skey ); return ($result); } function getExpiryDate($_CERTIFICATE){ $_CERT_DATA = openssl_x509_parse(file_get_contents($_CERTIFICATE)); return date('Ymd', $_CERT_DATA['validTo_time_t']); }
$path=$_SERVER['DOCUMENT_ROOT']; $certpath=$path."/your .pfx file"; $publickeypath=$path."/your .cer file"; $certpassword="your cert password"; require_once('xmlsecurity.php'); // for creating this file use link : https://github.com/robrichards/xmlseclibs $trn_id = "AuthDemoClient:public:". date('YmdHisU'); if (!$cert_store = file_get_contents($certpath)) { echo "Error: Unable to read the cert file\n"; exit; } if (openssl_pkcs12_read($cert_store, $cert_info, $certpassword)) { //print_r($cert_info["cert"]); //print_r($cert_info["pkey"]); } else { echo "Error: Unable to read the cert store.\n"; exit; } define("UIDAI_PUBLIC_CERTIFICATE" , $publickeypath); define("AUA_PRIVATE_CERTIFICATE" , $cert_info["pkey"]); date_default_timezone_set("Asia/Calcutta"); $date2= gmdate("Y-m-d\TH:i:s"); $date1 = date('Y-m-d\TH:i:s', time()); $ts='"'.$date1.'"';//date('Y-m-d\TH:i:s'); $pid_1='<Pid ts='.$ts.' ver="1.0"><Pv otp="'.$otp.'"/></Pid>'; $randkey = generateRandomString(); $SESSION_ID = $randkey; $skey1=encryptMcrypt($SESSION_ID); $skey=base64_encode($skey1); // generate ci code start $ci=getExpiryDate(UIDAI_PUBLIC_CERTIFICATE); // generate pid block code start
$pid=encryptPID($pid_1,$randkey); //hmac creation code start $hash=hash("SHA256",$pid_1,true); $hmac=encryptPID($hash,$randkey); $load_xml="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Auth xmlns=\"http://www.uidai.gov.in/authentication/uid-auth-request/1.0\" sa=\"public\" lk=\"your license key\" txn=\"$trn_id\" ver=\"1.6\" tid=\"public\" ac=\"your code from aadhaar\" uid=\"$aadhaarno\"><Uses pi=\"n\" pa=\"n\" pfa=\"n\" bio=\"n\" bt=\"\" pin=\"n\" otp=\"y\"/><Meta udc=\"UDC:001\" fdc=\"NC\" idc=\"NA\" pip=\"NA\" lot=\"P\" lov=\"$pincode\"/><Skey ci=\"$ci\">$skey</Skey><Data type=\"X\">$pid</Data><Hmac>$hmac</Hmac></Auth>";
>>Client application passes this encrypted data to AUA server which is then signed using Signing Certificate stored in HSM.
HSM is a hardware device that needs to be installed within your premises, some of the vendors you can buy a HSM device includes . The signing certificate should be stored in HSM device.
$dom = new DOMDocument(); $dom->loadXML($load_xml); // the XML you specified above. $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::C14N_COMMENTS); $objDSig->addReference($dom, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'),array('force_uri' =>'true')); $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private')); $objKey->loadKey($cert_info["pkey"], False); $objKey->passphrase = 'your certificate password'; $objDSig->sign($objKey, $dom->documentElement); $objDSig->add509Cert($cert_info["cert"]); $objDSig->appendSignature($dom->documentElement); $xml_string = $dom->saveXML(); $xml_string1 = urlencode($xml_string);
>>After Singing the Auth request. It is sent to ASA over secured communication channel. ASA then forwards it to UIDAI over leased line or similar secured network. In the code below ASA is NSDL
$curl = curl_init(); $url=""; //aadhar service url curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_POSTFIELDS,"eXml=A28".$xml_string1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); /* complete within 20 seconds */ curl_setopt($curl, CURLOPT_TIMEOUT, 20); $result = curl_exec($curl); curl_close($curl); $xml = @simplexml_load_string($result); $return_status=$xml['ret']; if($return_status=="y"){ $res=1; } if($return_status!="y"){ $res=0; } }else { $res='Aadhaar no not exist'; } return array('Message'=>$res); }
Upon receiving the Auth request, UIDAI verifies the ASA and AUA using License keys and digital signatures. If all is good, UIDAI decrypts the PID block to read the residents data and checks it against the CIDR(Central identification Data Repository). If all the given details of resident are correct, UIDAI will send YES or NO response accordingly.
The sample codes above can be directly implemented to create PID and receive responses from ASA in this case NSDL. Another thing to notice is that the sample code uses developer account provided by UIDAI.
As a licensed entity you would need to get the license from UIDAI, get onboarded with ASA like NSDL before you can start integrating.