Ringkasan emulasi kartu berbasis host

Banyak perangkat Android dengan fungsi NFC yang sudah mendukung emulasi kartu NFC. Pada umumnya, kartu diemulasi oleh chip terpisah di perangkat, yang disebut elemen pengaman. Banyak kartu SIM yang disediakan oleh operator nirkabel juga berisi elemen pengaman.

Android 4.4 dan yang lebih tinggi menyediakan metode emulasi kartu tambahan yang tidak melibatkan elemen pengaman, yang disebut emulasi kartu berbasis host. Hal ini memungkinkan aplikasi Android mengemulasi kartu dan berkomunikasi langsung dengan pembaca NFC. Topik ini menjelaskan cara kerja emulasi kartu berbasis host (HCE) di Android dan cara mengembangkan aplikasi yang mengemulasi kartu NFC menggunakan teknik ini.

Emulasi kartu dengan elemen pengaman

Saat emulasi kartu NFC disediakan menggunakan elemen pengaman, kartu yang akan diemulasi akan disediakan dalam elemen pengaman pada perangkat melalui aplikasi Android. Kemudian, saat pengguna meletakkan perangkat di atas terminal NFC, pengontrol NFC di perangkat akan mengarahkan semua data dari pembaca langsung ke elemen pengaman. Gambar 1 mengilustrasikan konsep ini:

Diagram dengan pembaca NFC yang melewati pengontrol NFC untuk mengambil informasi dari elemen pengaman
Gambar 1. Emulasi kartu NFC dengan elemen pengaman.

Elemen pengaman itu sendiri melakukan komunikasi dengan terminal NFC, dan tidak ada aplikasi Android yang terlibat dalam transaksi. Setelah transaksi selesai, aplikasi Android dapat mengkueri elemen aman secara langsung untuk status transaksi dan memberi tahu pengguna.

Emulasi kartu berbasis host

Saat kartu NFC diemulasi menggunakan emulasi kartu berbasis host, data akan dirutekan langsung ke CPU host, bukan dirutekan ke elemen aman. Gambar 2 mengilustrasikan cara kerja emulasi kartu berbasis host:

Diagram dengan pembaca NFC yang melewati pengontrol NFC untuk mengambil informasi dari CPU
Gambar 2. Emulasi kartu NFC tanpa elemen pengaman.

Kartu dan protokol NFC yang didukung

Diagram yang menunjukkan stack protokol HCE
Gambar 3. Stack protokol HCE Android.

Standar NFC menawarkan dukungan untuk berbagai protokol, dan ada berbagai jenis kartu yang dapat Anda emulasi.

Android 4.4 dan yang lebih baru mendukung beberapa protokol yang umum tersedia di pasar saat ini. Banyak kartu nirsentuh yang ada sudah didasarkan pada protokol ini, seperti kartu pembayaran nirsentuh. Protokol ini juga didukung oleh banyak pembaca NFC yang ada di pasaran saat ini, termasuk perangkat NFC Android yang berfungsi sebagai pembaca itu sendiri (lihat class IsoDep). Hal ini memungkinkan Anda membuat dan men-deploy solusi NFC menyeluruh untuk HCE hanya dengan menggunakan perangkat Android.

Secara khusus, Android 4.4 dan yang lebih tinggi mendukung emulasi kartu yang didasarkan pada spesifikasi ISO-DEP NFC-Forum (berdasarkan ISO/IEC 14443-4) dan memproses Application Protocol Data Unit (APDU) seperti yang ditentukan dalam spesifikasi ISO/IEC 7816-4. Android mewajibkan agar ISO-DEP hanya diemulasi di atas teknologi Nfc-A (ISO/IEC 14443-3 Jenis A). Dukungan untuk teknologi Nfc-B (ISO/IEC 14443-4 Jenis B) bersifat opsional. Gambar 3 mengilustrasikan lapisan semua spesifikasi ini.

Layanan HCE

Arsitektur HCE di Android didasarkan pada komponen Service Android (dikenal sebagai layanan HCE). Salah satu keunggulan utama layanan ini adalah dapat berjalan di latar belakang tanpa antarmuka pengguna. Hal ini cocok untuk banyak aplikasi HCE, seperti kartu loyalitas atau kartu multi-trip, yang tidak perlu diluncurkan oleh pengguna untuk digunakan. Sebagai gantinya, menempelkan perangkat dengan pembaca NFC akan memulai layanan yang benar jika belum berjalan dan menjalankan transaksi di latar belakang. Tentu saja, Anda bebas meluncurkan UI tambahan (seperti notifikasi pengguna) dari layanan jika diperlukan.

Pilihan layanan

Saat pengguna menempelkan perangkat ke pembaca NFC, sistem Android perlu mengetahui layanan HCE yang ingin diajak berkomunikasi oleh pembaca NFC. Spesifikasi ISO/IEC 7816-4 menentukan cara memilih aplikasi, yang dipusatkan pada ID Aplikasi (AID). AID terdiri dari maksimum 16 byte. Jika Anda mengemulasi kartu untuk infrastruktur pembaca NFC yang ada, AID yang dicari oleh pembaca tersebut biasanya terkenal dan terdaftar secara publik (misalnya, AID jaringan pembayaran seperti Visa dan MasterCard).

Jika ingin men-deploy infrastruktur pembaca baru untuk aplikasi Anda sendiri, Anda harus mendaftarkan AID Anda sendiri. Prosedur pendaftaran AID ditentukan dalam spesifikasi ISO/IEC 7816-5. Sebaiknya daftarkan AID sesuai dengan 7816-5 jika Anda men-deploy aplikasi HCE untuk Android, karena hal ini akan menghindari konflik dengan aplikasi lain.

Grup AID

Dalam beberapa kasus, layanan HCE mungkin perlu mendaftarkan beberapa AID dan ditetapkan sebagai pengendali default untuk semua AID guna menerapkan aplikasi tertentu. Beberapa AID dalam grup yang mengarah ke layanan lain tidak didukung.

Daftar AID yang disimpan bersama disebut grup AID. Untuk semua AID dalam grup AID, Android menjamin salah satu dari hal berikut:

  • Semua AID dalam grup diarahkan ke layanan HCE ini.
  • Tidak ada AID dalam grup yang diarahkan ke layanan HCE ini (misalnya, karena pengguna lebih memilih layanan lain yang juga meminta satu atau beberapa AID dalam grup Anda).

Dengan kata lain, tidak ada batasan ketika AID dalam grup dapat diarahkan ke satu layanan HCE, dan beberapa diarahkan ke layanan lain.

Grup dan kategori AID

Anda dapat mengaitkan setiap grup AID dengan kategori. Hal ini memungkinkan Android mengelompokkan layanan HCE berdasarkan kategori, yang kemudian memungkinkan pengguna menyetel default di tingkat kategori, bukan tingkat AID. Hindari menyebutkan AID di bagian aplikasi yang ditampilkan kepada pengguna, karena tidak berarti apa-apa bagi pengguna biasa.

Android 4.4 dan yang lebih tinggi mendukung dua kategori:

Mengimplementasikan layanan HCE

Untuk mengemulasi kartu NFC menggunakan emulasi kartu berbasis host, Anda perlu membuat komponen Service yang menangani transaksi NFC.

Memeriksa dukungan HCE

Aplikasi Anda dapat memeriksa apakah perangkat mendukung HCE dengan memeriksa fitur FEATURE_NFC_HOST_CARD_EMULATION. Gunakan tag <uses-feature> di manifes aplikasi untuk mendeklarasikan bahwa aplikasi Anda menggunakan fitur HCE, dan apakah fitur ini diperlukan agar aplikasi berfungsi atau tidak.

Pelaksanaan layanan

Android 4.4 dan yang lebih tinggi menyediakan class Service praktis yang dapat Anda gunakan sebagai dasar untuk menerapkan layanan HCE: class HostApduService.

Langkah pertama adalah memperluas HostApduService, seperti yang ditunjukkan dalam contoh kode berikut:

Kotlin

class MyHostApduService : HostApduService() {

    override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray {
       ...
    }

    override fun onDeactivated(reason: Int) {
       ...
    }
}

Java

public class MyHostApduService extends HostApduService {
    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
       ...
    }
    @Override
    public void onDeactivated(int reason) {
       ...
    }
}

HostApduService mendeklarasikan dua metode abstrak yang harus Anda ganti dan terapkan. Salah satunya, processCommandApdu(), dipanggil setiap kali pembaca NFC mengirim Application Protocol Data Unit (APDU) ke layanan Anda. APDU ditentukan dalam spesifikasi ISO/IEC 7816-4. APDU adalah paket tingkat aplikasi yang dipertukarkan antara pembaca NFC dan layanan HCE Anda. Protokol tingkat aplikasi tersebut bersifat half-duplex: pembaca NFC mengirimkan APDU perintah kepada Anda, dan menunggu Anda mengirim kembali APDU respons.

Seperti yang disebutkan sebelumnya, Android menggunakan AID untuk menentukan layanan HCE yang ingin diakses pembaca. Biasanya, APDU pertama yang dikirim pembaca NFC ke perangkat Anda adalah APDU SELECT AID; APDU ini berisi AID yang ingin diakses pembaca. Android mengekstrak AID tersebut dari APDU, me-resolve-nya ke layanan HCE, lalu meneruskan APDU tersebut ke layanan yang di-resolve.

Anda dapat mengirim APDU respons dengan menampilkan byte APDU respons dari processCommandApdu(). Perhatikan bahwa metode ini dipanggil di thread utama aplikasi Anda, yang tidak boleh Anda blokir. Jika Anda tidak dapat segera menghitung dan menampilkan APDU respons, tampilkan null. Kemudian, Anda dapat melakukan tugas yang diperlukan pada thread lain dan menggunakan metode sendResponseApdu() yang ditentukan dalam class HostApduService untuk mengirim respons setelah selesai.

Android terus meneruskan APDU baru dari pembaca ke layanan Anda, hingga salah satu hal berikut terjadi:

  • Pembaca NFC mengirim APDU SELECT AID lain, yang ditetapkan oleh OS ke layanan yang berbeda.
  • Link NFC antara pembaca NFC dan perangkat Anda rusak.

Dalam kedua kasus ini, penerapan onDeactivated() class Anda dipanggil dengan argumen yang menunjukkan kasus mana yang terjadi.

Jika menggunakan infrastruktur pembaca yang sudah ada, Anda harus menerapkan protokol tingkat aplikasi yang sudah ada yang diharapkan pembaca dalam layanan HCE Anda.

Jika menerapkan infrastruktur pembaca baru yang juga Anda kontrol, Anda dapat menentukan protokol dan urutan APDU sendiri. Coba batasi jumlah APDU dan ukuran data yang akan ditukarkan: tindakan ini akan memastikan bahwa pengguna hanya perlu meletakkan perangkatnya di atas pembaca NFC dalam waktu singkat. Batas atas yang wajar adalah sekitar 1 KB data, yang biasanya dapat ditukarkan dalam waktu 300 milidetik.

Deklarasi manifes layanan dan pendaftaran AID

Anda harus mendeklarasikan layanan dalam manifes seperti biasa, tetapi Anda juga harus menambahkan beberapa bagian tambahan ke deklarasi layanan:

  1. Untuk memberi tahu platform bahwa antarmuka HostApduService diterapkan oleh layanan HCE, tambahkan filter intent untuk tindakan SERVICE_INTERFACE ke deklarasi layanan Anda.

  2. Untuk memberi tahu platform tentang grup AID yang diminta oleh layanan ini, sertakan tag SERVICE_META_DATA <meta-data> dalam deklarasi layanan, yang mengarah ke resource XML dengan informasi tambahan tentang layanan HCE.

  3. Tetapkan atribut android:exported ke true, dan tetapkan izin android.permission.BIND_NFC_SERVICE dalam deklarasi layanan Anda. Poin pertama memastikan bahwa layanan dapat diikat oleh aplikasi eksternal. Kemudian, poin kedua menetapkan bahwa hanya aplikasi eksternal yang memiliki izin android.permission.BIND_NFC_SERVICE yang dapat diikat ke layanan Anda. Karena android.permission.BIND_NFC_SERVICE adalah izin sistem, izin ini secara efektif menetapkan bahwa hanya Android OS yang dapat diikat ke layanan Anda.

Berikut adalah contoh deklarasi manifes HostApduService:

<service android:name=".MyHostApduService" android:exported="true"
         android:permission="android.permission.BIND_NFC_SERVICE">
    <intent-filter>
        <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
    </intent-filter>
    <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
               android:resource="@xml/apduservice"/>
</service>

Tag metadata ini mengarah ke file apduservice.xml. Berikut adalah contoh file tersebut dengan satu deklarasi grup AID yang berisi dua AID eksklusif:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
           android:description="@string/servicedesc"
           android:requireDeviceUnlock="false">
    <aid-group android:description="@string/aiddescription"
               android:category="other">
        <aid-filter android:name="F0010203040506"/>
        <aid-filter android:name="F0394148148100"/>
    </aid-group>
</host-apdu-service>

Tag <host-apdu-service> harus berisi atribut <android:description> yang berisi deskripsi layanan yang mudah digunakan dan dapat Anda tampilkan di UI aplikasi. Anda dapat menggunakan atribut requireDeviceUnlock untuk menentukan bahwa kunci perangkat dibuka sebelum Anda memanggil layanan ini untuk menangani APDU.

<host-apdu-service> harus berisi satu atau beberapa tag <aid-group>. Setiap tag <aid-group> harus melakukan hal berikut:

  • Memuat atribut android:description yang berisi deskripsi grup AID yang mudah digunakan, cocok untuk ditampilkan di UI.
  • Menetapkan atribut android:category untuk menunjukkan kategori grup AID, seperti konstanta string yang ditentukan oleh CATEGORY_PAYMENT atau CATEGORY_OTHER.
  • Berisi satu atau beberapa tag <aid-filter>, yang masing-masing berisi satu AID. Tentukan AID dalam format heksadesimal, dan pastikan AID tersebut berisi jumlah karakter genap.

Aplikasi Anda juga harus memiliki izin NFC untuk mendaftar sebagai layanan HCE.

Penyelesaian konflik AID

Beberapa komponen HostApduService dapat diinstal di satu perangkat, dan AID yang sama dapat didaftarkan oleh lebih dari satu layanan. Android menentukan layanan mana yang akan dipanggil menggunakan langkah-langkah berikut:

  1. Jika aplikasi dompet default yang dipilih pengguna telah mendaftarkan AID, aplikasi tersebut akan dipanggil.
  2. Jika aplikasi dompet default belum mendaftarkan AID, layanan yang telah mendaftarkan AID akan dipanggil.
  3. Jika lebih dari satu layanan telah mendaftarkan AID, Android akan meminta pengguna layanan mana yang akan dipanggil.

Preferensi layanan latar depan

Aplikasi di latar depan dapat memanggil setPreferredService untuk menentukan layanan emulasi kartu yang harus dipilih saat aktivitas tertentu berada di latar depan. Preferensi aplikasi latar depan ini menggantikan penyelesaian konflik AID. Praktik ini direkomendasikan saat aplikasi mengantisipasi bahwa pengguna mungkin menggunakan emulasi kartu NFC.

Android 13 dan yang lebih baru

Agar lebih sesuai dengan daftar pilihan pembayaran default di UI Setelan, sesuaikan persyaratan banner ke ikon persegi. Idealnya, ikon ini harus identik dengan desain ikon peluncur aplikasi. Penyesuaian ini menciptakan lebih banyak konsistensi dan tampilan yang lebih rapi.

Android 12 dan yang lebih lama

Tetapkan ukuran banner layanan ke 260x96 dp, lalu tetapkan ukuran banner layanan dalam file XML metadata dengan menambahkan atribut android:apduServiceBanner ke tag <host-apdu-service>, yang mengarah ke resource yang dapat digambar. Berikut adalah contohnya:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:description="@string/servicedesc"
        android:requireDeviceUnlock="false"
        android:apduServiceBanner="@drawable/my_banner">
    <aid-group android:description="@string/aiddescription"
               android:category="payment">
        <aid-filter android:name="F0010203040506"/>
        <aid-filter android:name="F0394148148100"/>
    </aid-group>
</host-apdu-service>

Aplikasi Wallet

Android 15 dan yang lebih baru menyertakan peran aplikasi dompet default yang dapat dipilih pengguna dengan membuka Setelan > Aplikasi > Aplikasi Default. Ini menentukan aplikasi wallet default yang akan dipanggil saat terminal pembayaran diketuk. Android menganggap layanan HCE yang telah mendeklarasikan grup AID dengan kategori pembayaran sebagai aplikasi dompet.

Memeriksa apakah aplikasi Anda adalah aplikasi dompet default

Aplikasi dapat memeriksa apakah aplikasi tersebut adalah aplikasi dompet default dengan meneruskan RoleManager.ROLE_WALLET ke RoleManager.isRoleHeld().

Jika aplikasi Anda bukan default, Anda dapat meminta peran dompet default dengan meneruskan RoleManager.ROLE_WALLET ke RoleManager.createRequestRoleIntent().

Aset yang diperlukan untuk aplikasi Wallet

Untuk memberikan pengalaman pengguna dengan tampilan yang lebih menarik, aplikasi dompet HCE harus menyediakan banner layanan.

Mode Amati

Android 15 memperkenalkan fitur Observe Mode. Jika diaktifkan, Mode Pengamatan memungkinkan perangkat mengamati loop polling NFC dan mengirim notifikasi tentangnya ke komponen HostApduService yang sesuai sehingga dapat bersiap untuk berinteraksi dengan terminal NFC tertentu. HostApduService dapat menempatkan perangkat dalam Mode Pengamatan dengan meneruskan true ke setObserveModeEnabled(). Tindakan ini akan menginstruksikan stack NFC untuk tidak mengizinkan transaksi NFC dan sebagai gantinya mengamati loop polling secara pasif.

Filter loop polling

Anda dapat mendaftarkan filter loop polling untuk HostApduService menggunakan salah satu metode berikut:

Jika filter loop polling cocok dengan frame polling nonstandar, stack NFC akan merutekan frame polling tersebut ke HostApduService yang sesuai dengan memanggil metode processPollingFrames() -nya. Hal ini memungkinkan layanan mengambil langkah-langkah yang diperlukan untuk memastikan bahwa pengguna siap melakukan transaksi dan ingin melakukannya—misalnya, mengautentikasi pengguna. Jika pembaca NFC hanya menggunakan frame standar dalam loop polling-nya, stack NFC akan merutekan frame polling tersebut ke layanan latar depan yang diinginkan jika layanan tersebut berada di latar depan atau ke pemegang peran default wallet.

Notifikasi frame polling juga menyertakan pengukuran kekuatan medan khusus vendor yang dapat Anda ambil dengan memanggil getVendorSpecificGain(). Vendor dapat memberikan pengukuran menggunakan skala mereka sendiri selama sesuai dengan satu byte.

Merespons loop polling dan bertransisi keluar dari Mode Pengamatan

Saat siap melakukan transaksi, layanan dapat keluar dari Mode Pengamatan dengan meneruskan false ke setObserveModeEnabled(). Stack NFC kemudian akan mengizinkan transaksi untuk dilanjutkan.

Komponen HostApduService dapat menunjukkan bahwa Mode Pengamatan harus diaktifkan setiap kali merupakan layanan pembayaran pilihan dengan menetapkan shouldDefaultToObserveMode ke true dalam manifes atau dengan memanggil CardEmulation.setShouldDefaultToObserveModeForService().

Komponen HostApduService dan OffHostApduService juga dapat menunjukkan bahwa filter loop polling yang cocok dengan frame loop polling yang diterima harus menonaktifkan Mode Pengamatan secara otomatis dan mengizinkan transaksi dilanjutkan dengan menetapkan autoTransact ke true dalam deklarasi PollingLoopFilter dalam manifes.

Preferensi layanan latar depan

Aplikasi di latar depan dapat memanggil setPreferredService untuk menentukan layanan emulasi kartu yang harus dipilih saat aktivitas tertentu berada di latar depan. Preferensi aplikasi latar depan ini mengganti status Mode Pengamatan perangkat yang sesuai dengan nilai shouldDefaultToObserveMode untuk layanan tertentu, yang dapat ditetapkan dengan salah satu cara berikut:

Perilaku layar kunci dan layar nonaktif

Perilaku layanan HCE bervariasi berdasarkan versi Android yang berjalan di perangkat.

Android 15 dan yang lebih baru

Jika aplikasi Wallet default mengaktifkan Mode Pengamatan di perangkat yang mendukungnya, aplikasi tersebut akan mengganti perilaku buka kunci dan layar nonaktif, karena aplikasi tersebut mengontrol kapan transaksi dapat dilanjutkan. Beberapa aplikasi dompet mungkin mengharuskan perangkat dibuka kuncinya sebelum transaksi dapat dilanjutkan jika Mode Pengamatan tidak mendeteksi pola loop polling yang dapat diidentifikasi.

Developer dianjurkan untuk menggunakan perangkat pembaca mereka untuk memunculkan pola loop polling yang dapat diidentifikasi dan mendaftar untuk menangani pola tersebut dari aplikasi mereka.

Android 12 dan yang lebih baru

Pada aplikasi yang menargetkan Android 12 (API level 31) dan yang lebih tinggi, Anda dapat mengaktifkan pembayaran NFC tanpa mengaktifkan layar perangkat dengan menyetel requireDeviceScreenOn ke false.

Android 10 dan yang lebih baru

Perangkat yang menjalankan Android 10 (API level 29) atau yang lebih tinggi mendukung NFC Aman. Saat Amankan NFC aktif, semua emulator kartu (aplikasi host dan aplikasi off-host) tidak tersedia saat layar perangkat nonaktif. Saat Amankan NFC nonaktif, aplikasi off-host tersedia saat layar perangkat nonaktif. Anda dapat memeriksa dukungan Amankan NFC menggunakan isSecureNfcSupported().

Pada perangkat yang menjalankan Android 10 dan yang lebih tinggi, fungsi yang sama untuk menetapkan android:requireDeviceUnlock ke true berlaku seperti pada perangkat yang menjalankan Android 9 dan yang lebih rendah, tetapi hanya jika NFC Aman dinonaktifkan. Artinya, jika NFC Aman diaktifkan, layanan HCE tidak dapat berfungsi dari layar kunci terlepas dari setelan android:requireDeviceUnlock.

Android 9 dan yang lebih lama

Pada perangkat yang menjalankan Android 9 (API level 28) dan yang lebih rendah, pengontrol NFC dan pemroses aplikasi dinonaktifkan sepenuhnya saat layar perangkat dinonaktifkan. Oleh karena itu, layanan HCE tidak berfungsi saat layar nonaktif.

Selain itu, di Android 9 dan yang lebih rendah, layanan HCE dapat berfungsi dari layar kunci. Namun, hal ini dikontrol oleh atribut android:requireDeviceUnlock dalam tag <host-apdu-service> layanan HCE Anda. Secara default, kunci perangkat tidak diperlukan, dan layanan Anda akan dipanggil meskipun perangkat terkunci.

Jika Anda menetapkan atribut android:requireDeviceUnlock ke true untuk layanan HCE, Android akan meminta pengguna membuka kunci perangkat saat hal berikut terjadi:

  • pengguna mengetuk pembaca NFC.
  • pembaca NFC memilih AID yang ditetapkan ke layanan Anda.

Setelah kunci perangkat dibuka, Android akan menampilkan dialog yang meminta pengguna menempelkan sekali lagi untuk menyelesaikan transaksi. Tindakan ini diperlukan karena pengguna mungkin telah menjauhkan perangkat dari pembaca NFC untuk membuka kuncinya.

Koeksistensi dengan kartu elemen pengaman

Bagian ini ditujukan untuk developer yang telah men-deploy aplikasi yang mengandalkan elemen pengaman untuk emulasi kartu. Implementasi HCE Android dirancang agar berfungsi secara paralel dengan metode penerapan emulasi kartu lainnya, termasuk penggunaan elemen pengaman.

Koeksistensi ini didasarkan pada prinsip yang disebut perutean AID. Pengontrol NFC menyimpan tabel perutean yang berisi daftar aturan perutean (terbatas). Setiap aturan perutean berisi AID dan tujuan. Tujuan dapat berupa CPU host, tempat aplikasi Android berjalan, atau elemen pengamanan yang terhubung.

Saat pembaca NFC mengirim APDU dengan SELECT AID, pengontrol NFC akan mengurainya dan memeriksa apakah AID cocok dengan AID dalam tabel peruteannya. Jika cocok, APDU tersebut dan semua APDU yang mengikutinya akan dikirim ke tujuan yang terkait dengan AID, hingga APDU SELECT AID lain diterima atau link NFC rusak.

Gambar 4 mengilustrasikan arsitektur ini:

Diagram dengan pembaca NFC yang berkomunikasi dengan elemen pengaman dan CPU
Gambar 4. Android yang beroperasi dengan elemen pengaman dan emulasi kartu host.

Biasanya, pengontrol NFC juga memuat rute default untuk APDU. Jika AID tidak ditemukan dalam tabel perutean, rute default akan digunakan. Meskipun setelan ini mungkin berbeda antar-perangkat, perangkat Android perlu memastikan bahwa AID yang didaftarkan oleh aplikasi Anda diarahkan dengan benar ke host.

Aplikasi Android yang menerapkan layanan HCE atau yang menggunakan elemen pengaman tidak perlu mengonfigurasi tabel perutean; yang ditangani oleh Android secara otomatis. Android hanya perlu mengetahui AID mana yang dapat ditangani oleh layanan HCE dan mana yang dapat ditangani oleh elemen pengaman. Tabel perutean dikonfigurasi secara otomatis berdasarkan layanan yang diinstal dan yang dikonfigurasi pengguna sebagai layanan pilihan.

Bagian berikut menjelaskan cara mendeklarasikan AID untuk aplikasi yang menggunakan elemen pengaman untuk emulasi kartu.

Pendaftaran AID elemen pengaman

Aplikasi yang menggunakan elemen pengaman untuk emulasi kartu dapat mendeklarasikan layanan di luar host dalam manifesnya. Deklarasi layanan tersebut hampir sama dengan deklarasi layanan HCE. Pengecualian tersebut adalah sebagai berikut:

  • Tindakan yang digunakan dalam filter intent harus ditetapkan ke SERVICE_INTERFACE.
  • Atribut nama metadata harus ditetapkan ke SERVICE_META_DATA.
  • File XML metadata harus menggunakan tag root <offhost-apdu-service>.

    <service android:name=".MyOffHostApduService" android:exported="true"
           android:permission="android.permission.BIND_NFC_SERVICE">
      <intent-filter>
          <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
      </intent-filter>
      <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service"
                 android:resource="@xml/apduservice"/>
    </service>

Berikut adalah contoh file apduservice.xml yang sesuai yang mendaftarkan dua AID:

<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
           android:description="@string/servicedesc">
    <aid-group android:description="@string/subscription" android:category="other">
        <aid-filter android:name="F0010203040506"/>
        <aid-filter android:name="F0394148148100"/>
    </aid-group>
</offhost-apdu-service>

Atribut android:requireDeviceUnlock tidak berlaku untuk layanan di luar host, karena CPU host tidak terlibat dalam transaksi, sehingga tidak dapat mencegah elemen pengaman menjalankan transaksi saat perangkat terkunci.

Atribut android:apduServiceBanner diperlukan untuk layanan di luar host yang merupakan aplikasi pembayaran dan dapat dipilih sebagai aplikasi pembayaran default.

Pemanggilan layanan di luar host

Android tidak pernah memulai atau mengikat ke layanan yang dideklarasikan sebagai "off-host", karena transaksi yang sebenarnya dijalankan oleh elemen aman, bukan oleh layanan Android. Deklarasi layanan hanya memungkinkan aplikasi mendaftarkan AID yang ada di elemen pengaman.

HCE dan keamanan

Arsitektur HCE menyediakan satu bagian inti keamanan: karena layanan Anda dilindungi oleh izin sistem BIND_NFC_SERVICE, hanya OS yang dapat mengikat dan berkomunikasi dengan layanan Anda. Hal ini memastikan bahwa APDU yang Anda terima sebenarnya adalah APDU yang diterima oleh OS dari pengontrol NFC, dan APDU yang Anda kirim kembali hanya akan diarahkan ke OS, yang kemudian langsung meneruskan APDU ke pengontrol NFC.

Masalah terakhir yang tersisa adalah tempat Anda mendapatkan data yang dikirimkan aplikasi ke pembaca NFC. Bagian ini sengaja dipisahkan dalam desain HCE; tidak mempedulikan asal data, hanya memastikan bahwa data tersebut dipindahkan ke pengontrol NFC dan dikirim ke pembaca NFC dengan aman.

Untuk menyimpan dan mengambil data yang ingin dikirim dari layanan HCE dengan aman, Anda dapat, misalnya, mengandalkan Sandbox Aplikasi Android, yang memisahkan data aplikasi Anda dari aplikasi lain. Untuk detail selengkapnya tentang keamanan Android, baca Tips keamanan.

Parameter protokol dan detailnya

Bagian ini ditujukan untuk developer yang ingin mempelajari parameter protokol yang digunakan perangkat HCE selama fase aktivasi dan pencegahan konflik protokol NFC. Hal ini memungkinkan pembuatan infrastruktur pembaca yang kompatibel dengan perangkat HCE Android.

Aktivasi dan pencegahan konflik protokol Nfc-A (ISO/IEC 14443 jenis A)

Sebagai bagian dari aktivasi protokol Nfc-A, beberapa frame ditukarkan.

Di bagian pertama pertukaran, perangkat HCE menampilkan UID-nya; perangkat HCE harus diasumsikan memiliki UID acak. Artinya, setiap kali ditempelkan, UID yang ditampilkan kepada pembaca adalah UID yang dibuat secara acak. Oleh karena itu, pembaca NFC tidak boleh bergantung pada UID perangkat HCE sebagai bentuk autentikasi atau identifikasi.

Selanjutnya, pembaca NFC dapat memilih perangkat HCE dengan mengirim perintah SEL_REQ. Respons SEL_RES perangkat HCE setidaknya telah menetapkan bit ke-6 (0x20), yang menunjukkan bahwa perangkat mendukung ISO-DEP. Perhatikan bahwa bit lain dalam SEL_RES juga dapat ditetapkan, yang menunjukkan misalnya dukungan untuk protokol NFC-DEP (p2p). Karena bit lain dapat ditetapkan, pembaca yang ingin berinteraksi dengan perangkat HCE hanya perlu secara eksplisit memeriksa bit ke-6, dan tidak membandingkan SEL_RES lengkap dengan nilai 0x20.

Aktivasi ISO-DEP

Setelah protokol Nfc-A diaktifkan, pembaca NFC akan memulai aktivasi protokol ISO-DEP. Pembaca NFC akan mengirim perintah RATS (Request for Answer To Select). Pengontrol NFC menghasilkan respons RATS, yaitu ATS; ATS tidak dapat dikonfigurasi oleh layanan HCE. Namun, penerapan HCE harus memenuhi persyaratan Forum NFC untuk respons ATS, sehingga pembaca NFC dapat mengandalkan parameter ini yang ditetapkan sesuai dengan persyaratan Forum NFC untuk perangkat HCE apa pun.

Bagian di bawah ini menjelaskan lebih lanjut tentang setiap byte respons ATS yang disediakan oleh pengontrol NFC pada perangkat HCE:

  • TL: panjang respons ATS. Tidak boleh menunjukkan panjang yang lebih dari 20 byte.
  • T0: bit 5, 6, dan 7 harus ditetapkan di semua perangkat HCE, yang menunjukkan bahwa TA(1), TB(1), dan TC(1) disertakan dalam respons ATS. Bit 1 sampai 4 menunjukkan FSCI, yang mengodekan ukuran frame maksimum. Di perangkat HCE, nilai FSCI harus antara 0 jam dan 8 jam.
  • T(A)1: menentukan kecepatan bit antara pembaca dan emulator, serta apakah keduanya dapat bersifat asimetris. Tidak ada jaminan atau persyaratan kecepatan bit untuk perangkat HCE.
  • T(B)1: bit 1 sampai 4 menunjukkan Start-up Frame Guard time Integer (SFGI). Di perangkat HCE, SFGI harus kurang dari atau sama dengan 8 jam. Bit 5 sampai 8 menunjukkan Frame Waiting time Integer (FWI) dan mengodekan Frame Waiting Time (FWT). Di perangkat HCE, FWI harus kurang dari atau sama dengan 8 jam.
  • T(C)1: bit 5 menunjukkan dukungan untuk "fitur Protokol Lanjutan". Perangkat HCE mungkin mendukung "fitur Protokol Lanjutan", mungkin juga tidak. Bit 2 menunjukkan dukungan untuk DID. Perangkat HCE mungkin mendukung DID, mungkin juga tidak. Bit 1 menunjukkan dukungan untuk NAD. Perangkat HCE tidak boleh mendukung NAD dan menetapkan bit 1 ke nol.
  • Byte historis: Perangkat HCE dapat menampilkan hingga 15 byte historis. Pembaca NFC yang ingin berinteraksi dengan layanan HCE tidak boleh membuat asumsi tentang isi byte historis atau keberadaannya.

Perhatikan bahwa banyak perangkat HCE kemungkinan dibuat sesuai dengan persyaratan protokol yang telah ditentukan oleh jaringan pembayaran di EMVCo dalam spesifikasi "Protokol Komunikasi Nirsentuh". Khususnya:

  • FSCI di T0 harus antara 2 jam dan 8 jam.
  • T(A)1 harus ditetapkan ke 0x80, yang menunjukkan bahwa hanya kecepatan 106 kbit/dtk yang didukung, dan kecepatan bit asimetris antara pembaca dan emulator tidak didukung.
  • FWI di T(B)1 harus kurang dari atau sama dengan 7 jam.

Pertukaran data APDU

Seperti yang disebutkan sebelumnya, penerapan HCE hanya mendukung satu saluran logis. Upaya memilih aplikasi pada saluran logis yang berbeda tidak berfungsi di perangkat HCE.