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).
@Override
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 {
dep.connect();
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");
if(dep.isConnected()==true)
Log.d(TAG,"IS CONNECTED!");
else
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);
dep.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return null;
}
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:
and here is an excerpt of the EAC description:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With