主機型卡片模擬總覽

許多提供 NFC 功能的 Android 裝置都已支援 NFC 。資訊卡通常是由 也就是安全元素。無線電信業者提供的許多 SIM 卡 也包含安全元素

Android 4.4 以上版本提供另一種卡片模擬方法, 未包含名為「主機型卡片模擬」的安全元素。這個 可讓任何 Android 應用程式模擬卡片,並直接與 NFC 交談 讀取器。本主題說明主機卡模擬 (HCE) 如何運作 以及如何利用這款 這是標準文字處理技術

透過安全元素模擬卡片

使用安全元素進行 NFC 卡模擬時,卡片要 模擬結果會透過 Android 佈建到裝置上的安全元件中 應用程式。如此一來,當使用者透過 NFC 感應器將裝置拿到時,NFC 裝置上的控制器會將所有資料直接轉送至 元素。圖 1 說明瞭這個概念:

這張圖表顯示 NFC 讀卡機透過 NFC 控制器從安全元素擷取資訊
圖1. 透過安全元素模擬 NFC 卡。

安全元件本身會與 NFC 終端機進行通訊 交易中未涉及任何 Android 應用程式。交易完成後 Android 應用程式可以直接查詢安全元件的 交易狀態並通知使用者

主機型卡片模擬

使用主機型卡片模擬功能模擬 NFC 卡時,系統會轉送資料 而非轉送至安全元素。圖 2 說明主機卡模擬的運作方式:

這張圖表顯示 NFC 讀卡機透過 NFC 控制器擷取 CPU 資訊
圖2. 在沒有安全元素的情況下模擬 NFC 卡。

支援的 NFC 卡和通訊協定

顯示 HCE 通訊協定堆疊的圖表
圖3.Android 的 HCE 通訊協定堆疊

NFC 標準提供多種通訊協定的支援 您能模擬的各種資訊卡類型

Android 4.4 以上版本支援市面上的多種通訊協定 今天。許多現有的感應式卡片已經啟用這些協定。 例如感應式支付卡許多通訊協定同樣支援這些通訊協定 目前市面上的 NFC 讀卡機,包括功能 讀者 (請參閱 IsoDep 類別)。這可讓您建構及部署端對端 NFC 解決方案 HCE 只能使用 Android 裝置。

具體來說,Android 4.4 以上版本支援模擬根據 NFC-Forum ISO-DEP 規格 (依據 ISO/IEC 14443-4) 和程序 ISO/IEC 7816-4 中定義的應用程式通訊協定資料單位 (APDUs) 規格。Android 規定只在 Nfc-A 頂端模擬 ISO-DEP (ISO/IEC 14443-3 Type A) 技術。支援 Nfc-B (ISO/IEC 14443-4 Type B) 選用技術。圖 3 說明瞭上述所有容器的分層 規格。

HCE 服務

Android 的 HCE 架構是以 Android 為基礎 Service 元件 (稱為 HCE 服務)。這項服務的主要優點之一,是可以在 沒有使用者介面對多數 HCE 來說 例如會員卡或大眾運輸票證等 啟動要使用的應用程式。改為將裝置貼近 NFC 讀卡機 如果不是,卻未執行交易,請使用正確的服務 在背景執行當然,您可以啟動其他使用者介面 (例如 使用者通知)。

選擇服務

使用者將裝置靠近 NFC 讀卡機時,Android 系統會告知使用者 想要與 NFC 讀取器通訊的 HCE 服務通訊ISO/IEC 7816-4 規格會定義如何選取應用程式 應用程式 ID (AID)。AID 最多包含 16 個位元組。以模擬的方式 現有 NFC 讀取器基礎架構的卡片、這些讀卡機的 AID 尋找內容通常是知名且公開註冊 (例如 付款網路的 AID,例如 Visa 和 MasterCard。

如果要為應用程式部署新的讀取器基礎架構 必須註冊您的 AID。AID 的註冊程序定義如下: ISO/IEC 7816-5 規格建議您按照 7816-5 頻率註冊 AID 但請注意,當您部署適用於 Android 的 HCE 應用程式,可避免衝突 應用程式。

AID 群組

在某些情況下,HCE 服務可能需要註冊多個 AID,並設為 所有 AID 的預設處理常式,以便實作 應用程式。系統不支援群組中的部分 AID 傳送到其他服務。

由一起整理的 AID 清單稱為 AID 群組。針對 AID 群組,Android 保證下列其中一項:

  • 群組中的所有 AID 都會轉送至這項 HCE 服務。
  • 群組中沒有任何 AID 會轉送至這項 HCE 服務 (例如,因為 使用者偏好使用的其他服務,且該服務要求你的群組含有一或多個 AID )。

換句話說,中間沒有狀態,因此群組中的部分 AID 可 傳遞至另一項 HCE 服務

AID 群組和類別

您可以將每個 AID 群組與一個類別建立關聯。這樣一來,Android 就可以將 使用者可以依類別同時啟用 HCE 服務 預設為類別層級,而不是 AID 層級。避免提及 AID 應用程式的任何面向,因為這並不代表 與一般使用者

Android 4.4 以上版本支援兩種類別:

,瞭解如何調查及移除這項存取權。

實作 HCE 服務

如要使用主機型卡片模擬功能模擬 NFC 卡,您必須建立 處理 NFC 交易的 Service 元件。

確認 HCE 支援

應用程式可檢查裝置是否支援 HCE, FEATURE_NFC_HOST_CARD_EMULATION敬上 而不是每個特徵的分數使用 <uses-feature> 標記,宣告應用程式使用 HCE 以及應用程式是否必要運作。

服務實作

Android 4.4 以上版本提供便利的 Service 類別,可用於 做為實作 HCE 服務的基準: HostApduService 類別。

第一步是擴充 HostApduService,如以下程式碼所示 範例:

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 宣告了兩個您必須覆寫和執行的抽象方法。 其中一項 processCommandApdu()、 NFC 讀取器傳送應用程式通訊協定資料單位 (APDU) 時即會呼叫 以便將圖片傳入服務APDU 已按照 ISO/IEC 7816-4 規格定義。每日活躍使用者單人平均收益 是 NFC 讀取器之間交換的應用程式層級封包 管理 HCE 服務這個應用程式層級通訊協定為半雙工:NFC 讀取器 就會傳回 APDU 指令,並等候您在以下時間傳送回應 APDU: 傳回。

如先前所述,Android 會使用 AID 判斷 讀者喜歡跟我說話一般來說,NFC 讀取器的第一個 APDU 會傳送給 裝置的 APDU 為 SELECT AID;這個 APDU 包含讀者所需的 AID 這類語言Android 從 APDU 擷取 AID,將其解析為 HCE 並將 APDU 轉送至已解決的服務。

您可以傳回回應 APDU 的位元組, processCommandApdu()。請注意,此方法會在主執行緒上呼叫 這不應封鎖但如果無法運算並傳回 就會立即傳回空值。接著您就能 另一個執行緒,然後使用 sendResponseApdu()敬上 HostApduService 類別中定義的方法,以便在發生以下情況時傳送回應 完成。

Android 會持續將新的 APDU 從讀取器轉送至您的服務,直到 會發生下列情況:

  • NFC 讀取器傳送另一個 SELECT AID APDU,OS 會解析為 不同服務
  • NFC 讀卡機與裝置之間的 NFC 連結毀損。

在這兩種情況下,您的類別 onDeactivated()敬上 則會呼叫一個引數來指出這兩種情況發生。

如果您使用現有的閱讀器基礎架構,則須採用 讀取器只需讀取 HCE 服務所需的應用程式等級通訊協定

如果您要部署自己控管的新讀取器基礎架構 您可以自行定義通訊協定和 APDU 序列。嘗試限制 APDU 數量 以及要交換的資料大小:這可確保使用者 將裝置貼近 NFC 讀卡機一小段時間。A 罩杯 合理的上限約為 1 KB 資料,這類上限通常是 交換作業會在 300 毫秒內

服務資訊清單宣告和 AID 登錄

您必須照常在資訊清單中宣告服務,但必須新增一些 額外加入服務宣告

  1. 向平台說明這是採用 HostApduService 介面,新增意圖篩選器 SERVICE_INTERFACE

  2. 如要向平台判斷這項服務要求哪些 AID 群組,請加入 換 SERVICE_META_DATA敬上 服務宣告中的 <meta-data> 標記,指向 XML 含有 HCE 服務額外資訊

  3. android:exported 屬性設為 true,並要求使用 服務宣告中有 android.permission.BIND_NFC_SERVICE 權限。 前者可確保服務可繫結至外部應用程式。 接著是強制規定,只有採用 「android.permission.BIND_NFC_SERVICE」權限可繫結至服務。 android.permission.BIND_NFC_SERVICE 是系統權限,因此這項權限 強制規定只有 Android 作業系統可繫結至您的服務。

以下是 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>

這個中繼資料標記指向 apduservice.xml 檔案。以下是 這種檔案的單一 AID 群組宣告包含兩個 專屬 AID:

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

<host-apdu-service> 標記必須包含 <android:description> 屬性 ,為服務提供清楚易懂的說明 應用程式 UI 中您可以使用 requireDeviceUnlock 屬性指定 裝置處於解鎖狀態,您才能叫用這項服務處理 APDU。

<host-apdu-service> 必須包含一或多個 <aid-group> 標記。每項 必須使用 <aid-group> 標記才能執行以下操作:

  • 包含的 android:description 屬性包含容易使用 AID 群組的說明,適合顯示在 UI 中。
  • android:category 屬性設為表示 AID 的類別 其所屬群組,例如 CATEGORY_PAYMENT 定義的字串常數 或 CATEGORY_OTHER
  • 包含一或多個 <aid-filter> 標記,每個標記都包含一個 AID。 以十六進位格式指定 AID,並確認其中包含偶數 字元數。

您的應用程式也必須保持 NFC 權限才能註冊為 。

AID 衝突解決

單一裝置上可安裝多個 HostApduService 元件 不同的服務可以註冊同一個 AID。Android 會解析 AID 取決於 AID 所屬的類別,衝突情況也會有所不同。每項 類別可能有不同的衝突解決政策。

使用者或許可以針對部分類別 (例如付款) 選取預設值 啟用該服務。至於其他類別,則這項政策可能是 若發生衝突,請務必詢問使用者要叫用哪個服務。資訊 有關如何查詢特定類別的衝突解決政策,請參閱 getSelectionModeForCategory()

確認服務是否為預設服務

應用程式可以檢查自己的 HCE 服務是否為 篩選特定類別 isDefaultServiceForCategory()敬上 也能使用 Google Cloud CLI 或 Compute Engine API

如果服務不是預設服務,您可以要求將服務設為預設服務 使用 ACTION_CHANGE_DEFAULT

付款應用程式

Android 會認定 HCE 服務已宣告使用 payment 類別做為付款應用程式。Android 4.4 以上版本包含 頂層「設定」選單項目,稱為「tap &pay,其中列舉所有 這類付款應用程式使用者可在這個設定選單中 使用者輕觸付款終端機時要叫用的預設付款應用程式。

付款應用程式的必要資產

為提供更吸睛的使用者體驗,HCE 付款應用程式 必須提供服務橫幅。

Android 13 以上版本

如要讓「設定」使用者介面的預設付款選項清單更符合需求,請調整 正方形圖示的顯示規範在理想情況下,應該要與 應用程式啟動器圖示的設計這項調整可提高一致性, 看起來更簡潔

Android 12 以下版本

將服務橫幅的大小設為 260x96 dp,然後設定服務橫幅的大小 ,方法是將 android:apduServiceBanner 屬性加入 <host-apdu-service> 標記,指向可繪製資源。 範例如下:

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

螢幕關閉和螢幕鎖定行為

HCE 服務的行為因搭載的 Android 版本而異 裝置。

Android 12 以上版本

如果是指定 Android 12 (API 級別 31) 以上版本的應用程式,您可以啟用 NFC 輕鬆付款 requireDeviceScreenOnfalse

Android 10 以上版本

搭載 Android 10 (API 級別 29) 以上版本的裝置 安全 NFC。安全無虞 NFC 已開啟,所有卡片模擬器 (主機應用程式和非主機應用程式) 都處於 無法在裝置螢幕關閉時使用安全 NFC 關閉時,不在主機上 但裝置螢幕關閉時仍可使用。您可以檢查 安全 NFC 支援,方法是使用 isSecureNfcSupported()

在搭載 Android 10 以上版本的裝置上,可透過相同設定 與裝置一樣適用 android:requireDeviceUnlocktrue 搭載 Android 9 以下版本,但只會在安全 NFC 功能關閉時執行。也就是說 安全 NFC 已開啟,因此螢幕鎖定畫面無法使用 HCE 服務 無論 android:requireDeviceUnlock 的設定為何。

Android 9 以下版本

在搭載 Android 9 (API 級別 28) 以下版本的裝置上,NFC 控制器和 當應用程式處理器的螢幕顯示時,應用程式處理器就會完全關閉。 裝置已關閉。因此,即使螢幕關閉,HCE 服務將無法運作。

此外,在 Android 9 以下版本中,HCE 服務可以在螢幕鎖定畫面上正常運作。 不過,這項設定是由android:requireDeviceUnlock HCE 服務的 <host-apdu-service> 標記。根據預設,裝置解鎖為 不必使用,而且會叫用服務,即使裝置處於鎖定狀態也一樣。

如果將 HCE 的 android:requireDeviceUnlock 屬性設為 true 服務,Android 會在下列情況提示使用者解鎖裝置 發生:

  • 使用者輕觸 NFC 讀卡機。
  • NFC 讀卡機會選取已解決服務的 AID。

解鎖後,Android 會顯示對話方塊,提示使用者再次輕觸 完成交易。這是因為使用者可能將 裝置必須遠離 NFC 讀卡機才能解鎖。

與安全元件卡共存

本節適用於已部署應用程式的開發人員 需要仰賴安全元素才能模擬卡片Android 的 HCE 實作 經過特別設計,可與其他實作卡片的方法並行使用 模擬,包括使用安全元素。

這種共存是以 AID 轉送原則為基礎。NFC 控制器會保留由一份路徑清單 (有限) 的清單 不過,編寫這類演算法並不容易 因為我們無法寫出所有可能的規則每項轉送規則都包含一個 AID 和目的地。目的地可以 可以是主機 CPU、Android 應用程式執行的位置或連線的安全 元素。

當 NFC 讀取器透過 SELECT AID 傳送 APDU 時,NFC 控制器會剖析 並檢查 AID 是否與路由表格中的任何 AID 相符。如果是 符合,系統就會將 APDU 和之後的所有 APDU 都傳送至目的地 或是與 AID 相關聯,直到收到另一個 SELECT AID APDU 或 NFC 無效連結。

圖 4 說明此架構:

NFC 讀取器與安全元素與 CPU 通訊的圖表
圖4. Android 具有安全元件和主機卡片模擬。

NFC 控制器通常也包含 APDU 的預設路徑。如果 在路由表中找不到 AID,系統會使用預設路徑。雖然這是 設定可能會因裝置而異,且必須使用 Android 裝置 確保應用程式註冊的 AID 能正確轉送到 主機。

實作 HCE 服務或使用安全元素的 Android 應用程式 不必費心設定路徑資料表處理實體 Android 會自動執行。Android 只需要知道系統能處理哪些 AID 以及可透過安全元件處理的服務。轉送 系統會根據安裝的服務和 設為首選的使用者

下一節將說明如何為使用 用於模擬卡片的安全元素。

安全元素 AID 註冊

使用安全元素模擬卡片模擬體驗的應用程式可以宣告 非主機服務。這類服務的宣告 幾乎與 HCE 服務的宣告相同例外狀況如下: 如下:

  • 意圖篩選器中使用的動作必須設為 SERVICE_INTERFACE
  • 中繼資料名稱屬性必須設為 SERVICE_META_DATA
  • 中繼資料 XML 檔案必須使用 <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>
    

以下是對應的 apduservice.xml 檔案範例 註冊兩個 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>

android:requireDeviceUnlock 屬性不適用於非代管服務。 因為主機 CPU 不會參與交易,因此無法 防止安全元素在裝置 已鎖定。

必須為非代管服務提供 android:apduServiceBanner 屬性 能設為預設付款應用程式 應用程式。

非主機服務叫用

Android 一律不會啟動或繫結至宣告為「離線」的服務。 因為實際交易是由安全元件執行,而非 Android 服務服務宣告只是允許應用程式 會註冊安全元素上顯示的 AID。

HCE 與安全性

HCE 架構提供一核心安全防護: 會由 BIND_NFC_SERVICE敬上 系統權限,只有 OS 可以繫結至您的服務並與其通訊。 這可確保您收到的任何 APDU ,確實為收到的平均 APDU 而所有 APDU 只會退回給 NFC 控制器的作業系統 作業系統,而 APDU 會直接將 APDU 轉至 NFC 控制器。

最後一個問題是讓您取得應用程式傳送的資料 感應到 NFC 讀卡機這是在 HCE 設計中刻意分離;它會 不在乎資料來源,只要確保資料安全無虞 會傳輸至 NFC 控制器,並傳輸至 NFC 讀卡機。

以安全的方式儲存及擷取您想從 HCE 傳送的資料 例如,您可以只用 Android 應用程式沙箱 將您的應用程式資料與其他應用程式區隔開來。進一步瞭解 Android 請參閱安全性提示

通訊協定參數和詳細資料

本節可讓開發人員瞭解哪種通訊協定 參數 HCE 裝置在反碰撞和啟動階段中使用的 NFC 通訊協定這可以建構 與 Android HCE 裝置相容

Nfc-A (ISO/IEC 14443 type A) 通訊協定防衝突和啟用

啟用 Nfc-A 通訊協定後,系統會交換多個頁框。

在交換的第一部分,HCE 裝置會顯示其 UID。HCE 裝置 應假設為隨機 UID。也就是說,每當你使用 UID 系統向讀取器顯示的 UID 是隨機產生的 UID。因此 NFC 讀取器不應仰賴 HCE 裝置的 UID 做為 驗證或身分識別

接著,NFC 讀取器即可傳送SEL_REQ來選取 HCE 裝置 指令HCE 裝置的 SEL_RES 回應至少包含第 6 位元 (0x20) 設定,表示裝置支援 ISO-DEP。請注意 SEL_RES 可能也會設定,表示支援 NFC-DEP 範例 (p2p) 通訊協定。其他位元可能會設定,因此讀者會希望與 HCE 裝置應該只明確檢查第 6 位元,不要進行比較 值為 0x20 的完整 SEL_RES

啟用 ISO-DEP

啟用 Nfc-A 通訊協定後,NFC 讀取器就會啟動 ISO-DEP 通訊協定啟動傳送 RATS (要求提供答案) 指令NFC 控制器會產生 RATS 回應,也就是 ATS;ATS 並未 可由 HCE 服務設定但 HCE 實作項目必須符合 NFC 論壇 對 ATS 回應的需求,讓 NFC 讀取器能計入這些參數 視 NFC 論壇要求之任何 HCE 裝置而定。

下一節將進一步說明 ATS 的個別位元組 NFC 控制器在 HCE 裝置上提供的回應:

  • TL:ATS 回應的長度。不得指定大於 20 的長度 一個位元組
  • T0:所有 HCE 裝置都必須設定位元 5、6 和 7,表示 TA(1)、TB(1) 和 TC(1) 都包含在 ATS 回應中。位元 1 到 4 表示 FSCI。 影格大小上限在 HCE 裝置上,FSCI 的值必須 介於 0 到 8 小時
  • T(A)1:定義讀取器與模擬器之間的位元率,以及是否可以設定 不對稱HCE 裝置沒有位元率需求或保證。
  • T(B)1:位元 1 到 4 表示啟動影格防護時間整數 (SFGI)。啟用 HCE 裝置,SFGI 必須小於 8 小時。位元 5 到 8 表示影格正在等待 時間整數 (FWI) 和影格等待時間 (FWT) 的代碼。在 HCE 裝置上、FWI 不得超過 8 小時。
  • T(C)1:位元 5 表示支援「進階通訊協定功能」。HCE 裝置 不一定會支援「進階通訊協定功能」。位元 2 表示支援 。HCE 裝置不一定支援 DID。位元 1 表示支援 NAD。HCE 裝置不得支援 NAD,並且將位元 1 設為零。
  • 歷來位元組:HCE 裝置最多可以傳回 15 個歷史位元組。近場通訊 願意與 HCE 服務互動的讀者不應做出任何假設 歷來位元組的內容或其存在。

請注意,許多 HCE 裝置可能都符合通訊協定要求 在 EMVCo 的「感應式支付」 通訊協定」規格。請特別注意以下幾點:

  • T0 中的 FSCI 必須介於 2 小時至 8 小時之間。
  • T(A)1 必須設為 0x80,表明只有 106 kbit/s 的位元率為 以及讀取器和模擬器之間的非對稱位元率 支援。
  • T(B)1 中的 FWI 必須小於或等於 7 小時。

APDU 資料交換

如前所述,HCE 實作僅支援單一邏輯管道。 無法透過不同邏輯管道選取應用程式 或 HCE 裝置