Tổng quan về mô phỏng thẻ dựa trên máy chủ

Nhiều thiết bị chạy Android cung cấp chức năng NFC đã hỗ trợ quy trình mô phỏng thẻ NFC. Trong hầu hết trường hợp, thẻ được mô phỏng bằng một khối riêng biệt trong thiết bị, gọi là phần tử bảo mật. Nhiều thẻ SIM do nhà mạng không dây cung cấp cũng chứa một yếu tố bảo mật.

Android 4.4 trở lên cung cấp một phương thức bổ sung để mô phỏng thẻ không liên quan đến phần tử bảo mật, được gọi là mô phỏng thẻ dựa trên máy chủ. Việc này cho phép mọi ứng dụng Android mô phỏng một thẻ và giao tiếp trực tiếp với trình đọc NFC. Chủ đề này mô tả cách hoạt động của quy trình mô phỏng thẻ dựa trên máy chủ (HCE) trên Android và cách bạn có thể phát triển một ứng dụng mô phỏng thẻ NFC bằng kỹ thuật này.

Mô phỏng thẻ bằng phần tử bảo mật

Khi quy trình mô phỏng thẻ NFC được cung cấp bằng một phần tử bảo mật, thẻ cần mô phỏng sẽ được cấp phép trong phần tử bảo mật trên thiết bị thông qua một ứng dụng Android. Sau đó, khi người dùng giữ thiết bị trên thiết bị đầu cuối NFC, bộ điều khiển NFC trong thiết bị sẽ chuyển trực tiếp tất cả dữ liệu từ trình đọc đến phần tử bảo mật. Hình 1 minh hoạ khái niệm này:

Sơ đồ cho thấy đầu đọc NFC đi qua bộ điều khiển NFC để truy xuất thông tin từ một phần tử bảo mật
Hình 1. Mô phỏng thẻ NFC với phần tử bảo mật.

Phần tử bảo mật sẽ tự thực hiện quá trình giao tiếp với thiết bị đầu cuối NFC và không có ứng dụng Android nào tham gia vào quá trình giao dịch. Sau khi giao dịch hoàn tất, ứng dụng Android có thể truy vấn trực tiếp phần tử bảo mật để biết trạng thái giao dịch và thông báo cho người dùng.

Mô phỏng thẻ dựa trên máy chủ

Khi thẻ NFC được mô phỏng bằng quy trình mô phỏng thẻ dựa trên máy chủ lưu trữ, dữ liệu sẽ được chuyển trực tiếp đến CPU của máy chủ thay vì được chuyển đến một phần tử bảo mật. Hình 2 minh hoạ cách hoạt động của quy trình mô phỏng thẻ dựa trên máy chủ:

Sơ đồ cho thấy trình đọc NFC đi qua bộ điều khiển NFC để truy xuất thông tin từ CPU
Hình 2. Mô phỏng thẻ NFC không có phần tử bảo mật.

Giao thức và thẻ NFC được hỗ trợ

Sơ đồ minh hoạ ngăn xếp giao thức HCE
Hình 3. Ngăn xếp giao thức HCE của Android.

Các tiêu chuẩn NFC hỗ trợ nhiều giao thức và bạn có thể mô phỏng nhiều loại thẻ khác nhau.

Android 4.4 trở lên hỗ trợ một số giao thức phổ biến trên thị trường hiện nay. Nhiều thẻ không tiếp xúc hiện tại đã dựa trên các giao thức này, chẳng hạn như thẻ thanh toán không tiếp xúc. Các giao thức này cũng được nhiều trình đọc NFC trên thị trường hỗ trợ hiện nay, bao gồm cả các thiết bị NFC chạy Android tự hoạt động như trình đọc (xem lớp IsoDep). Điều này cho phép bạn xây dựng và triển khai giải pháp NFC toàn diện xoay quanh Trung tâm trợ giúp chỉ bằng các thiết bị chạy Android.

Cụ thể, Android 4.4 trở lên hỗ trợ mô phỏng các thẻ dựa trên thông số kỹ thuật ISO-DEP của Diễn đàn NFC (dựa trên ISO/IEC 14443-4) và xử lý Đơn vị dữ liệu giao thức ứng dụng (APDU) như xác định trong quy cách ISO/IEC 7816-4. Android chỉ yêu cầu mô phỏng ISO-DEP đối với công nghệ Nfc-A (ISO/IEC 14443-3 Loại A). Không bắt buộc phải hỗ trợ công nghệ Nfc-B (ISO/IEC 14443-4 Loại B). Hình 3 minh hoạ cách phân lớp của tất cả các quy cách này.

Dịch vụ HCE

Kiến trúc HCE trong Android dựa trên các thành phần Service của Android (được gọi là dịch vụ HCE). Một trong những ưu điểm chính của dịch vụ là có thể chạy ở chế độ nền mà không cần bất kỳ giao diện người dùng nào. Điều này phù hợp tự nhiên với nhiều ứng dụng HCE, chẳng hạn như thẻ khách hàng thân thiết hoặc thẻ đi phương tiện công cộng, mà người dùng không cần chạy ứng dụng để sử dụng. Thay vào đó, việc nhấn thiết bị vào trình đọc NFC sẽ khởi động đúng dịch vụ nếu dịch vụ chưa chạy và thực thi giao dịch ở chế độ nền. Tất nhiên, bạn có thể tuỳ ý chạy giao diện người dùng bổ sung (chẳng hạn như thông báo cho người dùng) trên dịch vụ của bạn khi thích hợp.

Lựa chọn dịch vụ

Khi người dùng nhấn một thiết bị vào máy đọc NFC, hệ thống Android cần biết dịch vụ HCE mà trình đọc NFC muốn giao tiếp với dịch vụ nào. Quy cách ISO/IEC 7816-4 xác định cách chọn ứng dụng, tập trung vào Mã ứng dụng (AID). AID bao gồm tối đa 16 byte. Nếu bạn mô phỏng thẻ cho một cơ sở hạ tầng đọc NFC hiện có, thì AID mà những độc giả đó tìm thường được đăng ký công khai và nổi tiếng (ví dụ: AID của các mạng thanh toán như Visa và MasterCard).

Nếu muốn triển khai cơ sở hạ tầng mới dành cho độc giả cho ứng dụng của mình, bạn phải đăng ký AID của riêng mình. Quy trình đăng ký cho AID được xác định trong quy cách ISO/IEC 7816-5. Bạn nên đăng ký AID theo 7816-5 nếu đang triển khai ứng dụng HCE cho Android, vì AID này giúp tránh xung đột với các ứng dụng khác.

Nhóm AID

Trong một số trường hợp, dịch vụ HCE có thể cần đăng ký nhiều AID và đặt làm trình xử lý mặc định cho tất cả các AID để triển khai một ứng dụng cụ thể. Một số AID trong nhóm chuyển sang một dịch vụ khác không được hỗ trợ.

Danh sách các AID được giữ cùng nhau được gọi là nhóm AID. Đối với mọi AID trong nhóm AID, Android đảm bảo một trong những điều sau:

  • Tất cả AID trong nhóm đều được chuyển đến dịch vụ HCE này.
  • Không có AID nào trong nhóm được chuyển đến dịch vụ HCE này (ví dụ: vì người dùng ưu tiên một dịch vụ khác mà đã yêu cầu một hoặc nhiều AID trong nhóm của bạn).

Nói cách khác, không có trạng thái ở giữa, trong đó một số AID trong nhóm có thể được chuyển đến một dịch vụ HCE và một số AID này sang dịch vụ khác.

Nhóm và danh mục AID

Bạn có thể liên kết mỗi nhóm AID với một danh mục. Điều này cho phép Android nhóm các dịch vụ HCE với nhau theo danh mục, qua đó cho phép người dùng đặt giá trị mặc định ở cấp danh mục thay vì cấp AID. Tránh đề cập đến AID trong bất kỳ phần nào dành cho người dùng của ứng dụng, vì chúng không có ý nghĩa gì đối với người dùng thông thường.

Android 4.4 trở lên hỗ trợ 2 danh mục:

Triển khai dịch vụ HCE

Để mô phỏng thẻ NFC bằng cách sử dụng quy trình mô phỏng thẻ dựa trên máy chủ lưu trữ, bạn cần tạo một thành phần Service xử lý các giao dịch NFC.

Kiểm tra xem có hỗ trợ HCE không

Ứng dụng có thể kiểm tra xem thiết bị có hỗ trợ HCE hay không bằng cách kiểm tra tính năng FEATURE_NFC_HOST_CARD_EMULATION. Sử dụng thẻ <uses-feature> trong tệp kê khai của ứng dụng để khai báo rằng ứng dụng của bạn sử dụng tính năng HCE và liệu ứng dụng đó có bắt buộc để hoạt động hay không.

Triển khai dịch vụ

Android 4.4 trở lên cung cấp một lớp Service tiện lợi mà bạn có thể dùng làm cơ sở để triển khai dịch vụ HCE: lớp HostApduService.

Bước đầu tiên là mở rộng HostApduService, như trong mã mẫu sau đây:

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 khai báo 2 phương thức trừu tượng mà bạn phải ghi đè và triển khai. Một trong số đó, processCommandApdu(), sẽ được gọi bất cứ khi nào trình đọc NFC gửi Đơn vị dữ liệu giao thức ứng dụng (APDU) đến dịch vụ của bạn. APDU được xác định trong quy cách ISO/IEC 7816-4. APDU là các gói cấp ứng dụng được trao đổi giữa đầu đọc NFC và dịch vụ HCE của bạn. Giao thức cấp ứng dụng đó có chế độ bán song công: trình đọc NFC sẽ gửi cho bạn một APDU lệnh và chờ bạn gửi lại một APDU phản hồi.

Như đã đề cập trước đó, Android sử dụng AID để xác định dịch vụ HCE mà trình đọc muốn trò chuyện. Thông thường, APDU đầu tiên mà trình đọc NFC gửi đến thiết bị của bạn là APDU SELECT AID; APDU này chứa AID mà trình đọc muốn trao đổi. Android sẽ trích xuất AID đó từ APDU, phân giải AID đó thành một dịch vụ HCE, sau đó chuyển tiếp APDU đó sang dịch vụ đã phân giải.

Bạn có thể gửi một APDU phản hồi bằng cách trả về các byte của APDU phản hồi từ processCommandApdu(). Lưu ý rằng phương thức này được gọi trên luồng chính của ứng dụng mà bạn không nên chặn. Nếu bạn không thể tính toán và trả về một APDU phản hồi ngay lập tức, hãy trả về giá trị rỗng. Sau đó, bạn có thể thực hiện thao tác cần thiết trên một luồng khác và sử dụng phương thức sendResponseApdu() được xác định trong lớp HostApduService để gửi phản hồi khi hoàn tất.

Android liên tục chuyển tiếp các APDU mới từ trình đọc đến dịch vụ của bạn cho đến khi một trong hai trường hợp sau xảy ra:

  • Máy đọc NFC sẽ gửi một APDU SELECT AID khác mà hệ điều hành sẽ phân giải sang một dịch vụ khác.
  • Đường liên kết NFC giữa máy đọc NFC và thiết bị của bạn bị hỏng.

Trong cả hai trường hợp này, quá trình triển khai onDeactivated() của lớp sẽ được gọi với một đối số cho biết quá trình triển khai nào đã xảy ra.

Nếu đang làm việc với cơ sở hạ tầng đọc hiện có, bạn phải triển khai giao thức cấp ứng dụng hiện có mà độc giả mong đợi trong dịch vụ HCE của bạn.

Nếu đang triển khai cơ sở hạ tầng đọc mới mà bạn kiểm soát, thì bạn có thể xác định giao thức và trình tự APDU của riêng mình. Cố gắng giới hạn số lượng APDU và kích thước dữ liệu cần trao đổi: điều này đảm bảo rằng người dùng chỉ phải giữ thiết bị trước đầu đọc NFC trong một khoảng thời gian ngắn. Giới hạn trên hợp lý là khoảng 1 KB dữ liệu, thường có thể trao đổi trong vòng 300 mili giây.

Khai báo tệp kê khai dịch vụ và đăng ký AID

Bạn phải khai báo dịch vụ của mình trong tệp kê khai như bình thường, nhưng cũng phải thêm một số phần khác vào phần khai báo dịch vụ:

  1. Để cho nền tảng biết rằng đây là một dịch vụ HCE triển khai giao diện HostApduService, hãy thêm một bộ lọc ý định cho hành động SERVICE_INTERFACE vào phần khai báo dịch vụ.

  2. Để cho nền tảng biết những nhóm AID nào được dịch vụ này yêu cầu, hãy thêm thẻ SERVICE_META_DATA <meta-data> vào phần khai báo dịch vụ, trỏ đến tài nguyên XML có thông tin bổ sung về dịch vụ HCE.

  3. Đặt thuộc tính android:exported thành true và yêu cầu quyền android.permission.BIND_NFC_SERVICE trong phần khai báo dịch vụ. Tính năng trước đảm bảo rằng dịch vụ có thể được liên kết bởi các ứng dụng bên ngoài. Sau đó, chính sách sau sẽ thực thi rằng chỉ những ứng dụng bên ngoài có quyền android.permission.BIND_NFC_SERVICE mới có thể liên kết với dịch vụ của bạn. Vì android.permission.BIND_NFC_SERVICE là một quyền của hệ thống, nên phương thức này sẽ thực thi hiệu quả việc chỉ hệ điều hành Android mới có thể liên kết với dịch vụ của bạn.

Sau đây là ví dụ về nội dung khai báo tệp kê khai 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>

Thẻ siêu dữ liệu này trỏ đến một tệp apduservice.xml. Sau đây là ví dụ về một tệp như vậy, trong đó có một nội dung khai báo nhóm AID chứa hai AID độc quyền:

<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>

Thẻ <host-apdu-service> phải chứa thuộc tính <android:description> chứa nội dung mô tả thân thiện với người dùng về dịch vụ mà bạn có thể hiển thị trong giao diện người dùng của ứng dụng. Bạn có thể sử dụng thuộc tính requireDeviceUnlock để chỉ định rằng thiết bị được mở khoá trước khi gọi dịch vụ này để xử lý các APDU.

<host-apdu-service> phải chứa một hoặc nhiều thẻ <aid-group>. Mỗi thẻ <aid-group> cần được thực hiện những việc sau:

  • Chứa thuộc tính android:description chứa nội dung mô tả thân thiện với người dùng về nhóm AID và phù hợp để hiển thị trong giao diện người dùng.
  • Đặt thuộc tính android:category để cho biết danh mục chứa nhóm AID, chẳng hạn như các hằng số chuỗi do CATEGORY_PAYMENT hoặc CATEGORY_OTHER xác định.
  • Chứa một hoặc nhiều thẻ <aid-filter>, mỗi thẻ chứa một AID duy nhất. Chỉ định AID ở định dạng thập lục phân và đảm bảo AID chứa số lượng ký tự đồng đều.

Ứng dụng của bạn cũng cần có quyền NFC để đăng ký làm dịch vụ Trung tâm trợ giúp.

Giải quyết xung đột AID

Bạn có thể cài đặt nhiều thành phần HostApduService trên một thiết bị và cùng một AID có thể được đăng ký bằng nhiều dịch vụ. Android giải quyết các xung đột AID theo cách khác nhau, tuỳ thuộc vào danh mục của AID. Mỗi danh mục có thể có một chính sách giải quyết xung đột khác nhau.

Đối với một số danh mục (chẳng hạn như thanh toán), người dùng có thể chọn dịch vụ mặc định trong giao diện người dùng của chế độ cài đặt Android. Đối với các danh mục khác, chính sách có thể là luôn hỏi người dùng cần gọi dịch vụ nào trong trường hợp xảy ra xung đột. Để biết thông tin về cách truy vấn chính sách giải quyết xung đột cho một danh mục nhất định, hãy xem getSelectionModeForCategory().

Kiểm tra xem dịch vụ của bạn có phải là dịch vụ mặc định không

Các ứng dụng có thể kiểm tra xem dịch vụ HCE có phải là dịch vụ mặc định cho một danh mục nhất định hay không bằng cách sử dụng API isDefaultServiceForCategory().

Nếu dịch vụ của bạn không phải là dịch vụ mặc định, bạn có thể yêu cầu đặt dịch vụ đó làm mặc định bằng cách sử dụng ACTION_CHANGE_DEFAULT.

Ứng dụng thanh toán

Android coi các dịch vụ HCE đã khai báo nhóm AID có danh mục payment (thanh toán) là ứng dụng thanh toán. Android 4.4 trở lên chứa mục nhập trong trình đơn Settings (Cài đặt) cấp cao nhất có tên là tap & pay (nhấn và thanh toán), mục này liệt kê tất cả các ứng dụng thanh toán như vậy. Trong trình đơn cài đặt này, người dùng có thể chọn ứng dụng thanh toán mặc định sẽ gọi khi nhấn vào một thiết bị thanh toán.

Phần tử bắt buộc cho ứng dụng thanh toán

Để mang lại trải nghiệm người dùng hấp dẫn hơn, các ứng dụng thanh toán HCE phải cung cấp biểu ngữ dịch vụ.

Android 13 trở lên

Để phù hợp hơn với danh sách lựa chọn thanh toán mặc định trong giao diện người dùng Cài đặt, hãy điều chỉnh yêu cầu biểu ngữ thành biểu tượng hình vuông. Tốt nhất là bạn nên giống hệt với thiết kế biểu tượng trình chạy ứng dụng. Sự điều chỉnh này sẽ tạo ra sự nhất quán và giao diện rõ ràng hơn.

Android 12 trở xuống

Đặt kích thước của biểu ngữ dịch vụ thành 260x96 dp, sau đó đặt kích thước của biểu ngữ dịch vụ trong tệp XML siêu dữ liệu bằng cách thêm thuộc tính android:apduServiceBanner vào thẻ <host-apdu-service> để trỏ đến tài nguyên có thể vẽ. Sau đây là ví dụ:

<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>

Hành vi tắt màn hình và khoá màn hình

Hành vi của các dịch vụ HCE sẽ khác nhau tuỳ theo phiên bản Android đang chạy trên thiết bị.

Android 12 trở lên

Trong các ứng dụng nhắm đến Android 12 (API cấp 31) trở lên, bạn có thể bật tính năng thanh toán qua NFC mà không cần bật màn hình của thiết bị bằng cách đặt requireDeviceScreenOn thành false.

Android 10 trở lên

Các thiết bị chạy Android 10 (API cấp 29) trở lên hỗ trợ NFC bảo mật. Khi NFC bảo mật đang bật, mọi trình mô phỏng thẻ (ứng dụng lưu trữ và ứng dụng bên ngoài máy chủ) sẽ không hoạt động khi màn hình thiết bị tắt. Mặc dù NFC bảo mật đang tắt, nhưng các ứng dụng bên ngoài máy chủ sẽ hoạt động khi màn hình thiết bị tắt. Bạn có thể kiểm tra khả năng hỗ trợ NFC bảo mật bằng cách sử dụng isSecureNfcSupported().

Trên các thiết bị chạy Android 10 trở lên, chức năng đặt android:requireDeviceUnlock thành true sẽ áp dụng tương tự như với các thiết bị chạy Android 9 trở xuống, nhưng chỉ khi NFC bảo mật được tắt. Tức là nếu NFC bảo mật được bật, các dịch vụ HCE sẽ không thể hoạt động trên màn hình khoá bất kể chế độ cài đặt của android:requireDeviceUnlock là gì.

Android 9 trở xuống

Trên các thiết bị chạy Android 9 (API cấp 28) trở xuống, bộ điều khiển NFC và bộ xử lý ứng dụng sẽ tắt hoàn toàn khi màn hình của thiết bị tắt. Do đó, dịch vụ HCE sẽ không hoạt động khi màn hình tắt.

Ngoài ra, trên Android 9 trở xuống, dịch vụ HCE có thể hoạt động trên màn hình khoá. Tuy nhiên, việc này được kiểm soát bởi thuộc tính android:requireDeviceUnlock trong thẻ <host-apdu-service> của dịch vụ HCE. Theo mặc định, việc mở khoá thiết bị là không bắt buộc và dịch vụ của bạn sẽ được gọi ngay cả khi thiết bị đang khoá.

Nếu bạn đặt thuộc tính android:requireDeviceUnlock thành true cho dịch vụ HCE, thì Android sẽ nhắc người dùng mở khoá thiết bị khi những trường hợp sau xảy ra:

  • người dùng nhấn vào một máy đọc thẻ NFC.
  • máy đọc NFC chọn một AID đã được phân giải cho dịch vụ của bạn.

Sau khi mở khoá, Android sẽ hiện một hộp thoại nhắc người dùng nhấn lại để hoàn tất giao dịch. Điều này là cần thiết vì người dùng có thể đã di chuyển thiết bị ra khỏi máy đọc NFC để mở khoá thiết bị.

Cùng tồn tại nhờ thẻ phần tử bảo mật

Phần này dành cho các nhà phát triển đã triển khai một ứng dụng dựa trên phần tử bảo mật để mô phỏng thẻ. Quy trình triển khai HCE của Android được thiết kế để hoạt động song song với các phương thức triển khai mô phỏng thẻ khác, bao gồm cả việc sử dụng các phần tử bảo mật.

Quá trình cùng tồn tại này dựa trên nguyên tắc định tuyến AID. Bộ điều khiển NFC lưu giữ một bảng định tuyến bao gồm một danh sách (có giới hạn) các quy tắc định tuyến. Mỗi quy tắc định tuyến chứa một AID và một đích đến. Đích đến có thể là CPU máy chủ, nơi các ứng dụng Android đang chạy hoặc một phần tử bảo mật đã kết nối.

Khi trình đọc NFC gửi một APDU có SELECT AID, bộ điều khiển NFC sẽ phân tích cú pháp mã đó và kiểm tra xem các AID có khớp với bất kỳ AID nào trong bảng định tuyến hay không. Nếu khớp, APDU đó và mọi APDU theo sau nó sẽ được gửi tới đích đến liên kết với AID, cho đến khi nhận được một APDU SELECT AID khác hoặc đường liên kết NFC bị hỏng.

Hình 4 minh hoạ cấu trúc này:

Sơ đồ cho thấy trình đọc NFC giao tiếp với cả phần tử bảo mật và CPU
Hình 4. Android hoạt động bằng cả phần tử bảo mật và quy trình mô phỏng thẻ máy chủ lưu trữ.

Bộ điều khiển NFC thường cũng chứa một tuyến mặc định cho các APDU. Khi không tìm thấy AID trong bảng định tuyến, tuyến mặc định sẽ được sử dụng. Mặc dù chế độ cài đặt này có thể khác nhau giữa các thiết bị, nhưng bạn cần phải sử dụng các thiết bị Android để đảm bảo rằng các AID mà ứng dụng của bạn đăng ký được chuyển đúng cách đến máy chủ.

Các ứng dụng Android triển khai dịch vụ HCE hoặc sử dụng phần tử bảo mật không phải lo lắng về việc định cấu hình bảng định tuyến; bảng này do Android xử lý tự động. Android chỉ cần biết AID nào có thể được dịch vụ HCE xử lý và phần tử bảo mật nào có thể xử lý những AID nào. Bảng định tuyến được định cấu hình tự động dựa trên những dịch vụ được cài đặt và những dịch vụ mà người dùng đã định cấu hình là ưu tiên.

Phần sau đây giải thích cách khai báo AID cho các ứng dụng sử dụng phần tử bảo mật để mô phỏng thẻ.

Đăng ký AID phần tử bảo mật

Các ứng dụng dùng phần tử bảo mật để mô phỏng thẻ có thể khai báo dịch vụ bên ngoài máy chủ trong tệp kê khai. Nội dung khai báo của một dịch vụ như vậy gần giống với nội dung khai báo về dịch vụ HCE. Sau đây là các trường hợp ngoại lệ:

  • Bạn phải đặt thao tác dùng trong bộ lọc ý định thành SERVICE_INTERFACE.
  • Thuộc tính tên siêu dữ liệu phải được đặt thành SERVICE_META_DATA.
  • Tệp XML siêu dữ liệu phải sử dụng thẻ gốc <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>
    

Sau đây là ví dụ về tệp apduservice.xml tương ứng đăng ký 2 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>

Thuộc tính android:requireDeviceUnlock không áp dụng cho các dịch vụ bên ngoài máy chủ lưu trữ, vì CPU của máy chủ không liên quan đến giao dịch và do đó không thể ngăn phần tử bảo mật thực hiện các giao dịch khi thiết bị bị khoá.

Thuộc tính android:apduServiceBanner là bắt buộc đối với các dịch vụ bên ngoài lưu trữ là ứng dụng thanh toán và có thể chọn làm ứng dụng thanh toán mặc định.

Lệnh gọi dịch vụ bên ngoài máy chủ

Android không bao giờ bắt đầu hoặc liên kết với một dịch vụ được khai báo là "ngoài máy chủ" vì các giao dịch thực tế là do phần tử bảo mật thực thi chứ không phải dịch vụ Android. Việc khai báo dịch vụ chỉ cho phép các ứng dụng đăng ký các AID có trên phần tử bảo mật.

HCE và bảo mật

Kiến trúc HCE cung cấp một yếu tố bảo mật cốt lõi: vì dịch vụ của bạn được bảo vệ bằng quyền hệ thống BIND_NFC_SERVICE, nên chỉ hệ điều hành mới có thể liên kết và giao tiếp với dịch vụ của bạn. Điều này đảm bảo rằng mọi APDU bạn nhận được đều thực sự là một APDU mà hệ điều hành nhận được qua bộ điều khiển NFC và mọi APDU mà bạn gửi lại chỉ chuyển đến hệ điều hành, từ đó sẽ chuyển tiếp trực tiếp các APDU tới bộ điều khiển NFC.

Mối lo ngại cuối cùng còn lại là nơi bạn lấy dữ liệu mà ứng dụng gửi tới trình đọc NFC. Điều này được tách riêng một cách có chủ ý trong thiết kế HCE; không quan tâm dữ liệu đến từ đâu, mà chỉ đảm bảo rằng dữ liệu được di chuyển an toàn đến bộ điều khiển NFC và ra đến đầu đọc NFC.

Để lưu trữ và truy xuất dữ liệu một cách an toàn mà bạn muốn gửi qua dịch vụ HCE, chẳng hạn, bạn có thể dựa vào Hộp cát của ứng dụng Android để tách riêng dữ liệu của ứng dụng với các ứng dụng khác. Để biết thêm thông tin chi tiết về vấn đề bảo mật trên Android, hãy đọc bài viết Mẹo bảo mật.

Tham số và thông tin chi tiết về giao thức

Phần này mà các nhà phát triển muốn tìm hiểu xem thiết bị HCE sử dụng các tham số giao thức nào trong giai đoạn chống xung đột và kích hoạt của giao thức NFC. Điều này cho phép xây dựng một cơ sở hạ tầng đọc tương thích với các thiết bị Android HCE.

Chống xung đột và kích hoạt giao thức Nfc-A (ISO/IEC 14443 loại A)

Trong quá trình kích hoạt giao thức Nfc-A, nhiều khung sẽ được trao đổi.

Trong phần đầu của quá trình trao đổi, thiết bị HCE hiển thị UID; các thiết bị HCE phải được giả định là có một UID ngẫu nhiên. Điều này có nghĩa là mỗi lần nhấn, UID hiển thị với người đọc là một UID được tạo ngẫu nhiên. Do đó, trình đọc NFC không nên lấy UID của thiết bị HCE làm phương thức xác thực hoặc nhận dạng.

Sau đó, trình đọc NFC có thể chọn thiết bị HCE bằng cách gửi lệnh SEL_REQ. Phản hồi SEL_RES của thiết bị HCE có ít nhất là bit thứ 6 (0x20), cho biết rằng thiết bị hỗ trợ ISO-DEP. Xin lưu ý rằng các bit khác trong SEL_RES cũng có thể được thiết lập, chẳng hạn như hỗ trợ giao thức NFC-DEP (p2p). Vì các bit khác có thể được đặt, nên những độc giả muốn tương tác với thiết bị HE chỉ nên kiểm tra rõ ràng bit thứ 6 và không so sánh SEL_RES hoàn chỉnh với giá trị 0x20.

Kích hoạt ISO-DEP

Sau khi giao thức Nfc-A được kích hoạt, trình đọc NFC sẽ bắt đầu kích hoạt giao thức ISO-DEP. Thao tác này sẽ gửi một lệnh RATS (Request for Reply To Select) (Yêu cầu trả lời để chọn). Bộ điều khiển NFC tạo phản hồi RATS (ATS). Dịch vụ HCE không thể định cấu hình ATS này. Tuy nhiên, các hoạt động triển khai HCE phải đáp ứng yêu cầu của Diễn đàn NFC cho phản hồi ATS. Vì vậy, trình đọc NFC có thể dựa vào các tham số này đang được đặt theo yêu cầu của Diễn đàn NFC cho mọi thiết bị HCE.

Phần dưới đây cung cấp thêm thông tin chi tiết về từng byte của phản hồi ATS do bộ điều khiển NFC cung cấp trên thiết bị HCE:

  • TL: độ dài của phản hồi ATS. Không được chỉ ra độ dài lớn hơn 20 byte.
  • T0: các bit 5, 6 và 7 phải được đặt trên tất cả các thiết bị HCE, chỉ ra TA(1), TB(1) và TC(1) có trong phản hồi ATS. Các bit từ 1 đến 4 cho biết FSCI, mã hoá kích thước khung hình tối đa. Trên các thiết bị HCE, giá trị của FSCI phải nằm trong khoảng từ 0h đến 8h.
  • T(A)1: xác định tốc độ bit giữa trình đọc và trình mô phỏng và xác định xem các tốc độ này có bất đối xứng hay không. Không có yêu cầu hoặc đảm bảo nào về tốc độ bit cho thiết bị HCE.
  • T(B)1: các bit 1 đến 4 biểu thị Số nguyên thời gian bảo vệ khung hình khởi động (SFGI). Trên các thiết bịHCE, SFGI phải <= 8 giờ. Các bit từ 5 đến 8 cho biết Số nguyên thời gian chờ khung hình (FWI) và mã hoá Thời gian chờ khung hình (FWT). Trên các thiết bị HCE, FWI phải <= 8 giờ.
  • T(C)1: bit 5 biểu thị khả năng hỗ trợ "Các tính năng giao thức nâng cao". Thiết bị HCE có thể hỗ trợ hoặc không hỗ trợ "Các tính năng Giao thức nâng cao". Bit 2 biểu thị tính năng hỗ trợ DID. Thiết bị HCE có thể hỗ trợ hoặc không hỗ trợ DID. Bit 1 cho biết có hỗ trợ NAD. Thiết bị HCE không được hỗ trợ NAD và đặt bit 1 về 0.
  • Số byte dữ liệu trong quá khứ: Thiết bị HCE có thể trả về tối đa 15 byte dữ liệu trong quá khứ. Trình đọc NFC sẵn sàng tương tác với các dịch vụ HCE không được giả định về nội dung của các byte trước đây hoặc sự hiện diện của các dịch vụ đó.

Xin lưu ý rằng nhiều thiết bị HCE có thể được điều chỉnh để tuân thủ các yêu cầu về giao thức mà các mạng thanh toán hợp nhất trong EMVCo đã chỉ định trong thông số kỹ thuật "Giao thức giao tiếp không tiếp xúc". Cụ thể:

  • FSCI ở T0 phải trong khoảng từ 2h đến 8h.
  • T(A)1 phải được đặt thành 0x80, cho biết chỉ tốc độ bit 106 kbit/giây được hỗ trợ và tốc độ bit bất đối xứng giữa trình đọc và trình mô phỏng không được hỗ trợ.
  • FWI trong T(B)1 phải <= 7h.

Trao đổi dữ liệu APDU

Như đã lưu ý trước đó, việc triển khai HCE chỉ hỗ trợ một kênh logic duy nhất. Việc cố gắng chọn ứng dụng trên nhiều kênh logic sẽ không hoạt động trên thiết bị HCE.