Menu

Get the encrypted iris data using an activity

This section provides information on how to scan the iris and get the encrypted iris data by following the activity based approach mentioned in the Android Discovery & API Calling section of the Aadhaar Registered Devices Technical Specification – Version 2.0.1.

Note: If the device does not support the Samsung India Identity APIs, then while querying for the activities supporting the intent, you cannot view the SamsungRDActivity.java in the list of ResolveInfo objects.

Steps involved in calling the APIs are as follows:

  1. Activate license: Once you activate the license, you can get the permissions to call the activity. For information about license activation, see To activate the license.

  2. Capture and device information: Query for the Activities supporting the intent action in.gov.uidai.rdservice.iris.CAPTURE using the android package manager queryIntentActivities() API method. Now start the activity with the activity name “SamsungRDActivity” using the startActivityForResult() API method. Pass the PidOptions XML as a bundle parameter with the name “PID_OPTIONS”. This starts the iris scan and data capture, and the preview is shown when the new Activity is launched. PidOptions XML is passed as input in bundle parameter and returns the (encrypted and signed PID), (encrypted and encoded session key), and (SHA-256 Hash of PID block, encrypted and then encoded) in PidData XML as mentioned in Aadhaar Registered Devices Technical Specification – Version 2.0.1. The PidData in returned in the onActivityResult() callback in string format. If you call the startActivityForResult() API method when a capture is on-going, then a SECIRIS_SENSOR_FAILURE is returned in errCode="" errInfo="" of PidData. You will get a success response in the onActivityResult() callback only if the device is registered with UIDAI. Registering with UIDAI happens once the device is connected to network.

    You can capture the iris image for a single eye, or dual eyes by passing the number “1” for single eye, and “2” for dual eyes in the iCount tag of input PidOptions XML.

    The PidOptions XML passed as input can have optionally filled demographics, OTP, and so on. The APIs returns the PidData XML which contains necessary information to form the auth/KYC request. The <Skey ci="">, <Hmac> and <Data type="X|P"> (encrypted PID) can be extracted from the PidData XML by parsing it. Using the encrypted PID, session key and HMAC is extracted and obtained. You can further construct the authentication or E-KYC XML request in your application for authenticating the user, or to get the e-KYC data from the Aadhaar server.

  3. Get the device information: The DeviceInfo is embedded within PidData XML obtained in the onActivityResult() callback in above step. DeviceInfo contains the device details which are required for constructing the auth request according to Aadhaar Registered Devices Technical Specification – Version 2.0.1. The details returned in the DeviceInfo XML tag within PidData contains the following informations.

    <DeviceInfo dpId="" rdsId="" rdsVer="" dc="" mi="" mc="" />

    Following are the DeviceInfo XML details and should be parsed by the application accordingly.

    dpId – Unique code assigned to registered device provider.

    rdsId – Unique ID of the certified registered device service.

    rdsVer – Registered devices service version.

    dc – Unique Registered device code.

    mi – Registered device model ID.

    mc – This attribute holds registered device public key certificate. This is signed with device provider key.

    The following code snippet shows how to use the APIs:

    int numberofeye = 2;
    boolean singleChecked = true;//false
    if(singleEye)
        numberofeye=1;
    String inputxml = String.format(                 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"                         + "<PidOptions ver=\"" + "1.0" +"\" "  +">" + "<Opts " + "iCount=\""                         + numeye                         + "\" "                         + "format=\""                         + "0"                         + "\" "                         + "iType=\""                         + "0"                         + "\" "                         + "pidVer=\""                         + "2.0"                         + "\" "                         + "env=\""                         + "S"                         + "\" "                         + "timeout=\""                         + "1200"                         + "\" />"                         + "<Demo lang=\"eng\">"                         + "<Pi "                         + "name=\""                         + dname                         + "\"/>"                         + "</Demo>"                         + "</PidOptions>");
    int requestCode = 3212;//can be any integer
    Intent act = new Intent("in.gov.uidai.rdservice.iris.CAPTURE");
    List<ResolveInfo> activities = packageManager.queryIntentActivities(act, 0);
    
    String pkgName = activities.get(0).activityInfo.packageName; //MAKE SURE YOU                    //HAVE SLECTED SAMSUNG RD SERVICE
    String activity = activities.get(0).activityInfo.name;
            act.setClassName(pkgName, activity);
            act.putExtra("PID_OPTIONS",getInputData());//getInputData() returns
                                                       // the PidOptions XML 
                                                       // in string format
    
    startActivityForResult(act,requestCode);//requestCode is some unique code
                                            //which u will get back in 
                                            //onActivityResult to distinguish
                                            // the results.
    }
    
    
    //OnActivity Result implementation
    
    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) {     
    
    super.onActivityResult(requestCode, resultCode, data); 
    
    switch(requestCode) { 
    
    case (3212) : { 
    if (resultCode == Activity.RESULT_OK) {
    String piddataxml = data.getStringExtra("PID_DATA");
    InputStream is = new ByteArrayInputStream(piddataxml.getBytes());
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setIgnoringComments(true);
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse(is);
    errcode = doc.getElementsByTagName("Resp").item(0).getAttributes().getNamedItem("errCode").getTextContent();
    errinfo = doc.getElementsByTagName("Resp").item(0).getAttributes().getNamedItem("errInfo").getTextContent();
    icount = doc.getElementsByTagName("Resp").item(0).getAttributes().getNamedItem("iCount").getTextContent();
    pid = doc.getElementsByTagName("Data").item(0).getTextContent();
    skey = doc.getElementsByTagName("Skey").item(0).getTextContent();
    ci = doc.getElementsByTagName("Skey").item(0).getAttributes().getNamedItem("ci").getTextContent();
    hmac = doc.getElementsByTagName("Hmac").item(0).getTextContent();
    type = doc.getElementsByTagName("Data").item(0).getAttributes().getNamedItem("type").getTextContent();
    dpId = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("dpId").getTextContent();
    rdsId = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("rdsId").getTextContent();
    rdsVer = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("rdsVer").getTextContent();
    dc = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("dc").getTextContent();
    mi = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("mi").getTextContent();
    mc = doc.getElementsByTagName("DeviceInfo").item(0).getAttributes().getNamedItem("mc").getTextContent();
                                  
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZZ", Locale.US);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC+5.30"));
    String ts = sdf.format(new Date());
    String authXML = String.format(
            "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + 
              "<" + ns2 + "Auth " + "ac=\"" + uidPrefs.getProperty("auaCode")
                    + "\" " + "lk=\"" + uidPrefs.getProperty("auaLicenseKey") + "\" " + "rc=\"" + (isRc? "Y":"N") +"\""+"sa=\""
                    + uidPrefs.getProperty("sa") + "\" " + "tid=\"registered\" " 
                    + "txn=\"" + txn + "\" " + "uid=\"" + uid + "\" " + "ver=\"2.0\" " + xmlnsBfd + xmlns + ">"
                    + "<Uses " + "bio=\"y\" " + "bt=\"IIR\" " + "otp=\"n\" " + "pa=\"n\" " + "pfa=\"n\" "
                    + "pi=\"" + pi + "\" " + "pin=\"n\"/>"
                    + "<Meta "  + "dc=\"" + dc + "\" " 
                    + "mi=\"" + mi + "\" " 
                    + "mc=\"" + mc + "\" " 
                    + "rdsId=\"" + rdsId + "\" "
                    + "rdsVer=\"" + rdsVer + "\" "
                    + "dpId=\"" + dpId + "\" "
                    + "udc=\"" + uidPrefs.getProperty("udc") + "\"/>" 
                    + "<Skey " + "ci=\"" + ci + "\">" + skey + "</Skey>" 
                    + "<Data "+ "type=\"X\">" + pid + "</Data>" 
                    + "<Hmac>" + hmac + "</Hmac>" + "</" + ns2 + "Auth>");
    
    Print.d(TAG + " :: Auth XML is:" + authXML);
    return authXML;
    }