Home » Android » Android NFC read data from ePassport

Android NFC read data from ePassport

Posted by: admin June 15, 2020 Leave a comment


I’m working on a ePassport Reader App, I’ve followed some older question and I’ve used the following code to connect to the passport successfully.
My problem is that I can’t understand how can I read all data (name, surname, photo….) stored into the passport.
Here is the code I’ve used, the app is working well (prompt when is near an NFC tag).

    protected String doInBackground(Tag... params) {

        //Tag tag = params[0];

        Intent intent = getIntent();

        //Log.d(TAG,"params " + intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));

        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        IsoDep dep = IsoDep.get(tag);

        if (dep == null) {
            // IsoDep is not supported by this Tag. 
            return null;

        byte[] CMD = {
                    (byte)0x00, /* CLA = 00 (first interindustry command set) */
                    (byte)0xA4, /* INS = A4 (SELECT) */
                    (byte)0x04, /* P1  = 04 (select file by DF name) */
                    (byte)0x0C, /* P2  = 0C (first or only file; no FCI) */
                    (byte)0x07, /* Lc  = 7  (data/AID has 7 bytes) */
                    /* AID = A0000002471001: */
                    (byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x02,
                    (byte)0x47, (byte)0x10, (byte)0x01

        byte[] GET_RANDOM = { 
                (byte) 0x00, // CLA Class        
                (byte) 0x84, // INS Instruction
                (byte) 0x00, // P1  Parameter 1
                (byte) 0x00, // P2  Parameter 2
                (byte) 0x0E  // LE  maximal number of bytes expected in result

            try {

                byte[] result = dep.transceive(CMD);// CONNECT

                Log.d(TAG, "result " + result[0] + " " + (byte)0x90);

                if (!(result[0] == (byte) 0x90 && result[1] == (byte) 0x00))
                        throw new IOException("could not select applet");

                    Log.d(TAG,"IS CONNECTED!");
                    Log.d(TAG,"ISN'T CONNECTED!");

                    result = dep.transceive(GET_RANDOM); // EXEC A CMD
                    int len = result.length;
                    if (!(result[len-2]==(byte)0x90 && result[len-1]==(byte) 0x00))
                       throw new RuntimeException("could not retrieve msisdn");

                    byte[] data = new byte[len-2];
                    System.arraycopy(result, 0, data, 0, len-2);
                    String str = new String(data);

                    Log.d(TAG, str);


            } catch (IOException e1) {

        return null;
How to&Answers:

You need the make a BAC (Basic Access Control) against your epassport to be able to read the basic informations printed on the passport (Country, Name, Surname, Nationality, Date of birth, Sex…) and the MRZ (Machine Readable Zone, that is to say the two big lines at the bottom of your passport). All this information is located in the DG (Data Group) 1, the photo is located in the DG2. You can find other informations in the other DG’s except for example the DG3 which needs an EAC (Extended Access Control) to be read because it contains sensitive data (fingerprints).

You can use the JMRTD library to read it from your Android Phone. A “demo” Android application is available on the market here. Otherwise, you can start reading the official documentation from ICAO (International Civil Aviation Organization) located here. At the end of this document, you can find some examples so you can make your own implementation of the BAC.

You can also look at the JMRTD source code to help you write your code. IMO it’s quite complicated to code but very interesting to learn. The code you wrote is a good start!


This is not an answer, but an addition to the info presented by Louis above.

Here is the list of the various Data Group reference numbers:

LDS Data Group reference numbers

and here is an excerpt of the EAC description:

Security for additional biometrics


Usually the ePassport is protected against normal access. So, before reading the ePass one has to optically scan the data page, send it to a secure server (border control, etc.). They will check it, do a optical data recognition () and provide secure access to the integrated RFID chip. Therefore, it is not possible to create an app reading out an official passport. You may just read the UID in some passports or just detect that there is “something”.