DOT Android NFC library

v2.2.1

Introduction

DOT Android NFC provides a component for NFC reading which is easy to integrate into an Android application. Supported documents are those which implement Machine Readable Travel Document (MRTD) standards as specified by International Civil Aviation Organization (ICAO).

Requirements

DOT Android NFC has the following requirements:

  • Android API level 21

Distribution

Maven Repository

DOT Android NFC is distributed as an Android library (.aar package) stored in the Innovatrics maven repository.

In order to integrate DOT Android NFC into your project, the first step is to include the Innovatrics maven repository and Google repository to your top level build.gradle file.

build.gradle
allprojects {
    repositories {
        jcenter()
        google()
        maven {
            url 'https://maven.innovatrics.com/releases'
        }
    }
}

Then, specify the dependency on DOT Android NFC library in the module’s build.gradle file. Dependencies of this library will be downloaded alongside the library.

build.gradle
dependencies {
    //…
    implementation "com.innovatrics.dot:dot-nfc:$dotDocumentVersion"
    //…
}

Permissions

DOT Android NFC declares the following permission in AndroidManifest.xml:

AndroidManifest.xml
<uses-permission android:name="android.permission.NFC" />

Basic Setup

Logging

Although logging is disabled by default, it can be enabled explicitly by using the following method from the com.innovatrics.android.commons.Logger class.

Logger.setLoggingEnabled(true);

The appropriate place for this call is within the onCreate() method of your subclass of android.app.Application. Each TAG of a log message starts with the prefix dot-nfc:.

This setting enables logging for all DOT Android libraries.
Keep in mind that logging should only be used for debug purposes, as it might produce a lot of log messages.

Components

Overview

DOT Android NFC provides a non-UI component for NFC reading. You may build your own UI using the DOT Android NFC functionality.

List of Non-UI Components

NFC TRAVEL DOCUMENT READER

The component for reading NFC enabled travel documents.

FLAT TAG STRUCTURE PARSER

The component for parsing flat tag structure in a data group as defined in Doc 9303.

Non-UI Components

NFC Travel Document Reader

The NfcTravelDocumentReader interface provides NFC reading functionality.

Create a NfcTravelDocumentReader:

Set<X509Certificate> authorityCertificates = CertificatesFactory.create(inputStream);
NfcTravelDocumentReaderConfiguration configuration = new NfcTravelDocumentReaderConfiguration.Builder()
    .timeoutMillis(timeoutMillis)
    .authorityCertificates(authorityCertificates)
    .build();
NfcTravelDocumentReader nfcTravelDocumentReader = NfcTravelDocumentReaderFactory.create(configuration);
NfcTravelDocumentReaderConfiguration.Builder arguments
  • (Optional) [10000] int timeoutMillis - The timeout only applies to ISO-DEP I/O operations on a Tag.

  • (Optional) [-] Set<X509Certificate> authorityCertificates - Certificates of trusted authorities. Certificates are required to successfully execute Passive Authentication.

To read NFC data, call the following method on the background thread:

TravelDocument travelDocument = nfcTravelDocumentReader.read(tag, nfcKey);

Tag represents NFC Tag discovered by NfcAdapter. NfcKey is the access key to NFC data.

NfcKey class

NfcKey is created from the travel document number, date of birth and date of expiry.

NfcKey nfcKey = NfcKey.of(documentNumber, dateOfExpiry, dateOfBirth);
Reading Process

Travel document reading process consists of three steps: Access Establishment, Passive Authentication, Active Authentication.

Access Establishment

There are two Access Establishment protocols Basic Access Control - BAC and Password Authenticated Connection Establishment - PACE. DOT Android NFC supports both BAC and PACE. To establish access, first PACE is used, if PACE fails BAC is used.

  • BAC: In order to access document using BAC, NFC Key is required. This NFC Key is created from the document number, date of birth and date of expiry.

  • PACE: The newer and more secure version of Access Establishment protocols. It uses NFC Key (weak password with low entropy) and generates cryptographically strong session keys.

Passive Authentication

The purpose of Passive Authentication is to validate the integrity of data stored on NFC chip. In other words, it verifies that data stored on NFC chip has not been altered. Passive Authentication has the following steps:

  • extract and validate Document Signing Certificate with CSCA Certificates from master list

  • verify that Security Data (EF.SOD) has been correctly signed by Document Signing Certificate

  • verify that hashes stored in EF.SOD are valid, i.e. hashes stored in EF.SOD are equal to hashes computed from data groups present on the document

Active Authentication

The purpose of Active Authentication is to verify that document is genuine, i.e. it is not a copy. Active Authentication has the following steps:

  • generate random challenge

  • request a signature for this challenge from the NFC chip

  • verify the signature using the public key stored in Data Group 15 (DG15)

The public key stored in DG15 can be RSA or ECDSA. DOT Android NFC supports both RSA and ECDSA.

Flat Tag Structure Parser

The FlatTagStructureParser interface parses a byte array into a flat map of data elements.

Create a FlatTagStructureParser:

FlatTagStructureParser flatTagStructureParser = FlatTagStructureParserFactory.create();

To parse a Data Group value, call the following method:

Map<Short, byte[]> elements = flatTagStructureParser.parse(bytes);

Following data structure is expected as an input:

ELEMENT_1_TAG, ELEMENT_1_LENGTH, ELEMENT_1_VALUE, ..., ELEMENT_N_TAG, ELEMENT_N_LENGTH, ELEMENT_N_VALUE

Such a value is parsed into this map:

Table 1. Map of Data Elements

Tag

Value

ELEMENT_1_TAG

ELEMENT_1_VALUE

…​

…​

ELEMENT_N_TAG

ELEMENT_N_VALUE

This is an example of a resulting map:

Table 2. Example of a map of Data Elements

Tag

Length

Value

0x5C

0x02

0x5F_5B

0x5F_5B

0x08

SPECIMEN (shown as text for readability)

Some country authorities may use this structure in the Optional Details. This data is present in TravelDocument.optionalDetails as a result of the NFC reading.

Appendix

Changelog

2.2.1 - 2022-01-25

Added
  • Class CertificatesFactory.

Fixed
  • Authority certificates compatibility on Android API level ⇐ 27.

  • Handling of lost connection.

2.2.0 - 2022-01-21

Added
  • Flat Tag Structure Parser component.

  • Interface FlatTagStructureParser.

  • Class FlatTagStructureParserFactory.

2.1.0 - 2022-01-19

Added
  • Class OptionalDetails.

  • Class attribute TravelDocument.optionalDetails.

Changed
  • Data type of AdditionalPersonalDetails.nameOfHolder to NameOfHolder.

Fixed
  • Passive Authentication for documents that are out of their validity period.

  • Resolving JPEG image format (enum ImageFormat).

  • Passive Authentication.

2.0.0 - 2021-12-02

Added
  • Enum AccessControlProtocol.

  • Class AdditionalDocumentDetails.

  • Class AdditionalPersonalDetails.

  • Class DisplayedSignatureOrUsualMark.

  • Class EncodedIdentificationFeaturesFace.

  • Class MachineReadableZoneInformation.

  • Class NameOfHolder.

  • Class NfcTravelDocumentReaderConfiguration.

  • Class NfcTravelDocumentReaderFactory.

Changed
  • groupId com.innovatrics.android to com.innovatrics.dot.

  • Minimum Android API level to 21.

  • Target Android API level to 31.

  • Class TravelDocumentAccessFailedException to AccessControlException.

  • Enum ActiveAuthentication.Status to ActiveAuthenticationStatus.

  • Enum PassiveAuthentication.Status to PassiveAuthenticationStatus.

  • Class NfcTravelDocumentReader to an interface NfcTravelDocumentReader.

  • Structure of class TravelDocument.

Fixed
  • Active Authentication.

1.0.0 - 2020-05-27

Added
  • First major release.