【譯】基於主機的卡仿真(Host-based Card Emulation)


基於主機的卡仿真(Host-based Card Emulation)

能提供NFC功能很多Android手機已經支持NFC卡模擬。在大多數情況下,該卡是由設備中的單獨的芯片仿真,所謂的安全元件。由無線運營商提供了許多的SIM卡還包含一個安全元件。

 

安卓4.4引入卡仿真的附加方法,該方法不涉及安全元件,稱為基於主機的卡模擬。這允許任何Android應用程序來模擬卡,並直接與NFC讀取器。本文檔介紹了如何基於主機的卡仿真( HCE )適用於Android和如何使用這種技術開發的應用程序,模擬的NFC卡。

帶安全元件的卡仿真(Card Emulation with a Secure Element)

當采用安全元件提供的NFC卡仿真,要被仿真的卡是通過Android應用程序配置到該設備上的安全元件。然后,當用戶將設備放在一個NFC終端上,在設備安卓設備上的NFC控制器轉發所有數據直接從讀卡器到安全元件。圖1示出了這一概念。

圖1.卡仿真與安全元件

安全元件本身進行與NFC終端的通信,安卓應用程序並沒有參與通信,通信結束后,安卓應用程序可以直接查詢安全元件的通信狀態,並通知用戶。

基於主機的卡仿真(Host-based Card Emulation)

當使用基於主機的卡仿真模擬的NFC卡,這些數據被傳輸到運行在安卓應用程序上的主機CPU,而不是NFC協議的幀傳輸到安全元件上,圖2說明了如何基於主機的卡仿真

圖2,NFC卡仿真沒有安全元件。

支持NFC卡和協議(Supported NFC Cards and Protocols)

NFC標准提供了許多不同協議的支持,並且不同類型的卡可以仿真。


安卓4.4支持現在在市場上普遍的許多協議,許多現有的非接觸卡是基於這些協議,如非接觸式支付卡。這些協議也被目前市場上許多NFC讀卡器所支持,包括Android NFC設備充當讀卡器(見IsoDep類)。這使您可以構建和只使用Android的設備周圍HCE部署一個終端到終端的NFC解決方案。


具體來說,安卓4.4支持模擬卡是基於NFC-Forum的ISO-DEP規范(基於ISO / IEC 14443-4)和過程應用協議單元(APDU)在ISO / IEC 7816-4規范中定義,Android的授權只在NFC-A(ISO-IEC 14443-3 A型)技術上仿效ISO-DEP。支持NFC-B(ISO/IEC14443-4類型B)的技術是可選的。所有這些規范的分層顯示在圖3中。

圖3.安卓的HCE協議棧

HCE服務

在安卓上HCE架構師基於安卓的服務組件(稱為“HCE services”)。一個服務的主要優點是,運行在后台沒有任何用戶界面。對於許多HCE應用這是很適合的,如忠誠或公交卡,用戶不需要啟動應用程序來使用它,相反,NFC讀卡器啟動相應的服務(如果尚未運行),並在后台執行通信,當然,你可以自由地從服務啟動額外的用戶界面(如用戶通知),如果是有意義的。

服務選擇(Service selection)

當用戶點擊一個設備的NFC讀卡器,安卓系統需要知道NFC讀卡器實際上想要那些服務通信,這就是ISO / IEC 7816-4規范進來:它定義了一種方法來選擇應用,圍繞應用ID(AID )為中心。一個AID最多由16個字節,如果你仿真卡用一個現有的NFC讀卡器設備,這些讀卡器都在尋找通常是眾所周知的公開注冊的(例如如Visa和MasterCard的AIDS)。


如果你想要為了你的應用程序部署新的讀卡器設備,你需要注冊自己的AID(s),AIDs注冊程序在ISO / IEC 7816-5規范中定義。谷歌建議注冊一個AID按7816-5 ,如果你正在部署為Android一HCE應用程序,它會避免與其他應用程序沖突。

AID組(AID groups)

在某些情況下, HCE服務可能需要注冊多個設備,以實現一個特定的應用程序,它需要確保它是默認的處理程序,對於所有的這些AIDs(如在一個組的一些AIDs到其他的服務)。


一個AID組是一個AIDs清單,應視為屬於在一起的操作系統,對於一個組的所有AID,安卓保證以下幾點:


*該組的所有AIDs能被連接到這個HCE 服務上


*本組中沒有AIDs連接到這個HCE服務上(例如,因為用戶首選了其他的服務,這個服務請求了在你的組里的一個或多個AIDS)


換句話說,沒有中間狀態,中間狀態指的是組中的一些AIDs被連接到一個HCE服務中,一些連接到其他的HCE服務中。

AID組和類別(AID groups and categories)

每個AID組能夠和一個類別關聯起來,這樣就允許安卓把HCE服務按照類別組織在一起,而這又使用戶可以在類級別而不是AID級別設置的默認值。一般情況下,避免在你的應用中的任何面向用戶部分提及AIDs:AIDs對於普通用戶而言沒有意義的。


安卓4.4支持兩種類別:CATEGORY_PAYMENT(包括行業標准的支付應用程序)和CATEGORY_OTHER (所有其他HCE應用程序) 。


注意:在CATEGORY_PAYMENT類別中僅有一個AID組可在系統中的任何給定時間被激活。通常情況下,這將是一個應用程序,解析主要的信用卡支付protcols並可以在任何商家合作。


對於閉環支付應用程序,只能在一個商家(如儲值卡) ,你應該使用CATEGORY_OTHER 。在這一類的AID組可以始終處於活動狀態,並且通過NFC讀寫器中的AID選擇,如果有必要可以優先考慮。


實現一個HCE服務(Implementing an HCE Service)


要使用基於主機的卡仿真模擬的NFC卡,您需要創建一個處理NFC通信服務組件。

檢查HCE支持

您的應用程序可以檢查設備是否支持HCE通過檢查FEATURE_NFC_HOST_CARD_EMULATION功能。您應該使用<uses-feature>標記在你的應用程序的清單中聲明你的應用程序使用HCE功能,以及它是否是必需的應用程序功能或沒有。

服務實現

安卓4.4自帶的,可以用來作為實現HCE服務的基礎便利服務類:HostApduService類​​。因此,第一步是要繼承HostApduService 。

 1 public class MyHostApduService extends HostApduService {
 2     @Override
 3     public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
 4        ...
 5     }
 6     @Override
 7     public void onDeactivated(int reason) {
 8        ...
 9     }
10 }

HostApduService 聲明了兩個需要重寫和實現的抽象方法,如上面代碼所示。


processCommandApdu ()被調用當一個NFC讀卡器發送一個應用協議數據單元(APDU)到你的服務里。APDU是在ISO / IEC 7816-4規格中定義。APDU是應用程序級的數據包被用來NFC讀卡器與你的HCE服務交換。應用層協議時半雙工:在NFC讀卡器將發送給您一個APDU命令,它會等待你的發送一個響應APDU。


注:ISO / IEC 7816-4規范還定義了多個邏輯通道,在那里你可以有不同的邏輯通道多路並行的APDU交換的概念。Android的HCE但是實現只支持一個單一的邏輯通道,所以有APDU的只有單線程交流。


正如前面提到的,Android設備使用AID確定讀卡器想要與哪個HCE服務通信,通常情況下,NFC讀卡器發送到您的設備的第一個APDU是一個“SELECT AID ” APDU,這個APDU包含了NFC讀卡器想要通信的AID,安卓從APDU提前AID,解析到HCE服務,然后轉發該APDU的解決服務。


您可以通過返回從processCommandApdu響應APDU (的字節)發送一個響應APDU。請注意,這個方法就會被調用應用程序的主線程,它不應該被阻塞。所以,如果你不能計算,並立即返回一個響應APDU ,則返回null 。你可以在另外的線程做必要的工作。並使用在HostApduService類中定義的sendResponseApdu ( )方法發送響應。


安卓將繼續轉發新的APDU從讀卡器到你的服務。直至:


1、NFC讀卡器發送另一個“SELECT AID ” APDU ,其中操作系統解析到不同的服務;


2、在NFC讀卡器和設備之間的NFC鏈路斷開。


在這兩種情況下,你的類的onDeactivated ( )執行被調用的參數表明這兩者的發生。


如果您正在使用現有的讀卡器設備,你需要在你的HCE服務里面實現現有的讀卡器期望的應用級協議。


如果你要部署你控制的新的讀卡器設備,你可以定義你自己的協議和APDU序列。一般來說盡量限制的APDU的數量和需要交換的數據的大小:這可以確保您的用戶將只需要保持他們的設備在NFC讀卡器很短的時間。一個上限大小為1K的數據,通常可在300毫秒交換。

服務清單申報和AID注冊(Service manifest declaration and AID registration)

您的服務必須在manifest像往常一樣進行聲明,但一些額外的塊必須被添加到服務聲明。


首先,要告訴大家,這是一個HCE服務實現HostApduService接口的平台,為您服務聲明必須包含一個意圖過濾器的SERVICE_INTERFACE action。


另外,告訴平台,AIDs被服務所要求,一個SERVICE_META_DATA <meta-data>標簽必須包含在服務的聲明,指向與有關HCE服務的附加信息的XML資源。


最后,你必須設置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文件。如下:

<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>屬性。該requireDeviceUnlock屬性可以用來指定該設備必須解鎖之前,這項服務可以被調用來處理APDU的。


<host-apdu-service>必須包含一個或多個<aid-group>標記。每個<aid-group>標簽要求:


*包含一個android:description屬性,包含一個用戶友好描述適,合在UI顯示description屬性。
*用android:category 屬性設置為顯示類的AID組所屬,如通過CATEGORY_PAYMENT或CATEGORY_OTHER定義的字符串常量。
*每個<aid-group>必須包含一個或多個<aid-filter>標簽,其中每個都包含一個單一的AID,AID必須以十六進制格式指定,並包含偶數個字符。

AID沖突的解決(AID Conflict Resolution)

多個HostApduServicez組件可以安裝在一台設備上並在同一AID可以由一個以上的服務進行注冊。安裝平台解決AID沖突依賴於AID屬於哪個類別。每個類別都可能有不同的沖突解決策略。
例如,對於某些類別(如付款) ,用戶可能能夠在Android用戶界面的設置選擇默認服務。對於其他類別的政策,就應該總是問哪個服務是在發生沖突時要調用的用戶。要查詢某一類的沖突解決策略,請參閱getSelectionModeForCategory ( ) 。

檢查如果你的服務是默認(Checking if your service is the default)

應用程序可以檢查自己的HCE服務是否是某一類的默認服務使用isDefaultServiceForCategory (單元名,字符串)的API 。
如果你的服務是不是默認的,你可以要求它作出的默認值。見ACTION_CHANGE_DEFAULT 。

支付應用(Payment Applications)

安卓認為,有“payment”類別的一個已宣布的AID組作為支付應用服務。而Android 4.4版本包含所謂的“挖掘與支付”頂層設置菜單項,其中列舉了所有此類支付應用程序。在這種設置菜單,用戶可以選擇當一個支付終端被觸發,將調用默認的支付應用。

支付應用程序所需的資源

為了提供更視覺吸引力的用戶體驗,HCE支付應用程序必須為他們的服務提供一個額外資源:所謂服務的一面旗幟。
該資資源大小應260x96 DP ,並且可以在你的元數據的XML文件中加入了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>

屏幕關閉和鎖屏行為(Screen Off and Lock-screen Behavior)

當該設備的屏幕被關閉時,目前安卓實現NFC控制器和應用處理器完全關閉,當屏幕關閉的時候,HCE服務將要不起作用。
然而HCE服務可以從lock-screen功能:這是由android:< host-apdu-service >標記的requireDeviceUnlockattribute HCE服務。默認情況下,設備不需要解鎖,你的服務將調用即使設備被鎖定。


如果你對你的HCE服務設置了android:requireDeviceUnlock 屬性為TURE,安卓將提示用戶解鎖設置,當你點擊一個NFC讀卡器來選擇一個AID為了解決你的服務。解鎖后,安卓將顯示一個對話框提示用戶再次點擊完成通信,這是必要的,因為用戶可能已經遠離NFC讀卡器設備為了解鎖它。

與安全元件共存卡(Coexistence with Secure Element Cards)

本節感興趣的開發人員已經部署的應用程序依賴於一個安全元件卡模擬,安卓的HCE實現並行設計工作與其他的方法實現卡模擬,包括使用安全元件。


注意:安卓不提供APIs對於直接與一個安全元件直接通信。

 

這種共存是基於一個原則稱為:“AID routing”:NFC控制器保持一個路由表,由一個(有限)的路由規則列表,每個路由規則包含一個AID和目的,目標可以是主機CPU ( Android應用程序正在其上運行) ,或連接的安全元件。


當NFC讀卡器發送一個含有“SELECT AID”的APDU,NFC控制器解析它並檢查這個AIDs是否與它的路由表中的AID匹配,這個APDU和跟隨它之后的所有APDU將要發送到與這個AID相關聯的的目的地。直到另一個“SELECT AID ” APDU被接收或在NFC鏈路斷開。


注意:而ISO / IEC 7816-4定義“部分匹配”的概念,這是目前沒有被HCE的Android設備支持。


這種體系結構示於圖4中。

圖4.安卓操作安全元件盒host-card仿真

NFC控制器通常還包含一個默認的APDUs路由,如果一個AID在路由表中沒有發現,這個默認的路由表被使用。從安卓4.4開始,默認的路由需要設置到主機CPU中。這意味着,路由表通常只包含需要到一個安全元件的AIDs。


實現一個HCE服務或使用一個安全元件的Android應用程序不必擔心配置路由表,它由安卓自動實現。安卓僅僅需要知道哪個AIDs可以通過HCE服務處理以及哪些可以通過安全元件來處理。根據該服務的安裝和用戶已經配置為優選的,路由表被自動配置。


我們已經描述了如何聲明AIDs對於HCE服務,接下來部分解釋對於用一個安全元件的卡仿真的應用如何聲明AIDs.

安全元件AID注冊(Secure element AID registration)

使用一個安全元件來卡仿真的應用程序可以再其清單中聲明一個所謂的“off host service”,這種服務的聲明幾乎和聲明一個HCE服務一樣,不同點:
*在意向過濾器中使用的動作必須設置為SERVICE_INTERFACE 。
*元數據的name屬性必須設置為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_ervice"
               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 屬性必須被支付應用的關主機服務使用,以及為了能夠選擇作為默認的支付應用。

關閉主機服務調用(Off host service invocation)

Android的本身永遠不會啟動或綁定到聲明為“關主”的服務。這是因為實際的交易由安全元件,並且不執行安卓服務本身。這個服務聲明只是允許應用程序在安全元件上注冊AIDs。

HCE和安全(HCE and Security)

HCE架構本身提供一個核芯片的安全性:因為你的服務是由BIND_NFC_SERVICE系統權限保護,只有操作系統可以結合並與您的服務進行通信。這可以確保您收到任何APDU實際上是由操作系統從NFC控制器收取的。你回發的任何APDU僅會去操作系統,這反過來又直接轉發的APDU到NFC​​控制器。


核心剩下的部分是,你得到你的數據,你的應用程序發送到NFC​​閱讀器,這是故意去耦在HCE設計:它並不關心其中的數據從何而來,它只是確保它安全地運到了NFC控制器和出了NFC讀寫器。
為安全地存儲和檢索您想要發送的數據從你HCE服務,你可以,例如,依賴於Android應用程序沙箱,隔離應用程序從其他應用程序的數據。為更多的細節在Android上安全、閱讀安全提示 .

協議參數和細節(Protocol parameters and details)

這部分是對於開發人員,想了解協議參數HCE設備使用期間防撞和NFC的激活階段協議。這允許建立一個基礎設施,與安卓HCE設備兼容。


Nfc-A(ISO / IEC 14443 A型)協議防撞和激活(Nfc-A (ISO/IEC 14443 type A) protocol anti-collision and activation)作為Nfc-A協議的一部分,激活、多幀交換。


交換的第一部分,HCE設備將要生成它自己的UID,HCE設備應被假定為有一個隨機的UID,這意味着,在每一個抽頭,即呈現給讀卡器的UID將是隨機產生的UID。正因為如此, NFC讀寫器不應該依賴於HCE設備身份驗證或識別的一種形式的UID 。


在NFC讀取器可以通過發送SEL_REQ命令后選擇HCE設備。HCE的SEL_RES響應設備將至少有6位(0 x20),表明該設備支持ISO-DEP。SEL_RES可能集中注意,其他部分,例如支持NFC-DEP指示(p2p)協議。因為其他可能,想要與HCE設備交互的讀卡器應該顯式地檢查第六位,和沒有比較完整的SEL_RES 0x20的值。

ISO-DEP激活(ISO-DEP activation)

之后, NFC -A協議被激活時,ISO -DEP協議激活由NFC讀取器啟動。它發出一個"RATS" (Request for Answer To Select) 命令,RATS響應,該ATS ,完全由NFC控制器產生,而不是由HCE服務配置。然而, HCE實現都必須滿足ATS服務響應NFC格式的要求,因此NFC讀寫器可以對這些參數按照任何HCE設備NFC規定被設置計數。


下面的部分提供了一個HCE設備上提供的NFC控制器的ATS響應的單個字節的詳細信息:


TL:ATS響應的長度,表示的長度不能大於20個字節。
T0:5、6和7位必須在所有的HCE設備設置,顯示TA(1), TB(1) 和 TC(1) 包含在ATS響應中。1到4位表示FSCI,編碼的幀的最大尺寸,對HCE設備FSCI的值必須是0H和8h之間。
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表示為DID支持。 HCE設備可能會或可能不支持DID 。位1表示的NAD支持。 HCE設備必須不支持NAD和設置位1至零。
歷史字節: HCE設備可以返回多達15個歷史字節。 NFC讀寫器願與HCE服務互動不應對歷史字節或它們的存在內容的假設。
注意許多HCE設備可能符合協議要求支付網絡聯合EMVCo指定在“非接觸通信協議規范。特別是:
FSCI在T0必須是2小時和8小時之間。
T(A ) 1必須設置為0x80 ,表示只支持106 kbit / s的比特率,並且不支持閱讀器和仿真器之間的不對稱比特率。
FWI在T( B) 1必須< = 7小時。

APDU的數據交換(APDU data exchange)

如前所述, HCE實現只支持一個單一的邏輯通道。嘗試選擇不同的邏輯通道的應用將不是一個HCE設備上工作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM