Android使用NFC模拟M卡实现 (一)
Android使用NFC模拟M卡实现 (一)
Android使用NFC模拟M卡实现 (二)
Android使用NFC模拟M卡实现 (三)
在百度找一遍,没有一篇,讲的比较通俗易懂的文件。讲解Android 的NFC 功能 card emulation。
略有点用的附在下面。
参考: 修改配置文件方式 |
自己动手,丰衣足食。那首先就得看官方的文档。
https://developer.android.google.cn/guide/topics/connectivity/nfc/hce
那就的细看,都翻译下。我的半桶水英语水平,向谷歌翻译借力。
如果想了解具体的,必须细看本文,只想结果,只想撸,那就看我的另篇:Android使用NFC模拟M卡实现 (二)
原文全拷过来,进行翻译备注,此次文档是API 28,勉强作下面官方翻译。
Host-based card emulation overview
基于主机的卡仿真概述
Many Android-powered devices that offer NFC functionality already support NFC card emulation. In most cases, the card is emulated by a separate chip in the device, called a secure element. Many SIM cards provided by wireless carriers also contain a secure element.
许多的Android设备提供NFC功能已经支持NFC卡仿真。在大多数情况下,卡的模拟在设备中有单独芯片,称为安全元件。无线运营商提供的许多SIM卡也包含安全元件。
Android 4.4 introduces an additional method of card emulation that does not involve a secure element, called host-based card emulation. This allows any Android application to emulate a card and talk directly to the NFC reader. This document describes how host-based card emulation (HCE) works on Android and how you can develop an app that emulates an NFC card using this technique.
Android4.4引入了另一种卡仿真方法,该方法不涉及称为基于主机的卡仿真的安全元素。这允许任何Android应用程序模拟卡并直接与NFC阅读器对话。本文档介绍了基于主机的卡仿真(HCE)如何在Android上运行,以及如何使用此技术开发模拟NFC卡的应用程序。
Card Emulation with a secure element
具有安全元素的卡仿真
When NFC card emulation is provided using a secure element, the card to be emulated is provisioned into the secure element on the device through an Android application. Then, when the user holds the device over an NFC terminal, the NFC controller in the device routes all data from the reader directly to the secure element. Figure 1 illustrates this concept.
当使用安全元件提供NFC卡仿真时,要仿真的卡通过Android应用程序提供到设备上的安全元件中。然后,当用户将设备保持在NFC终端上时,设备中的NFC控制器将来自读取器的所有数据直接路由到安全元件。
Figure 1. NFC card emulation with a secure element.
图1说明了这个概念。
The secure element itself performs the communication with the NFC terminal, and no Android application is involved in the transaction at all. After the transaction is complete, an Android application can query the secure element directly for the transaction status and notify the user.
安全元件本身执行与NFC终端的通信,并且交易中根本不涉及Android应用程序。事务完成后,Android应用程序可以直接查询安全元素以获取事务状态并通知用户。
Host-based card emulation
基于主机的卡仿真
When an NFC card is emulated using host-based card emulation, the data is routed to the host CPU on which Android applications are running directly, instead of routing the NFC protocol frames to a secure element. Figure 2 illustrates how host-based card emulation works.
使用基于主机的卡仿真模拟NFC卡时,数据将路由到直接运行Android应用程序的主机CPU,而不是将NFC协议帧路由到安全元件。图2说明了基于主机的卡仿真的工作原理。
Figure 2. NFC card emulation without a secure element.
图2.没有安全元件的NFC卡仿真。
Supported NFC cards and protocols支持的NFC卡和协议The NFC standards offer support for many different protocols, and there are different types of cards that can be emulated. NFC标准提供对许多不同协议的支持,并且可以模拟不同类型的卡。 Android 4.4 supports several protocols that are common in the market today. Many existing contactless cards are already based on these protocols, such as contactless payment cards. These protocols are also supported by many NFC readers in the market today, including Android NFC devices functioning as readers themselves (see the Android 4.4支持当今市场上常见的几种协议。许多现有的非接触式卡已经基于这些协议,例如非接触式支付卡。当今市场上的许多NFC阅读器也支持这些协议,包括作为阅读器本身的Android NFC设备(参见 Specifically, Android 4.4 supports emulating cards that are based on the NFC-Forum ISO-DEP specification (based on ISO/IEC 14443-4) and process Application Protocol Data Units (APDUs) as defined in the ISO/IEC 7816-4 specification. Android mandates emulating ISO-DEP only on top of the Nfc-A (ISO/IEC 14443-3 Type A) technology. Support for Nfc-B (ISO/IEC 14443-4 Type B) technology is optional. The layering of all these specifications is shown in the figure 3. 具体而言,Android 4.4支持仿真基于NFC论坛ISO-DEP规范(基于ISO / IEC 14443-4)和ISO / IEC 7816-4规范中定义的处理应用协议数据单元(APDU)的卡。Android要求仅在Nfc-A(ISO / IEC 14443-3 A类)技术之上模拟ISO-DEP。支持Nfc-B(ISO / IEC 14443-4 B类)技术是可选的。所有这些规范的分层如图3所示。
| Figure 3. Android's HCE protocol stack. 图3. Android的HCE协议栈。 |
HCE services
HCE服务 【即Host-based card emulation services】
The HCE architecture in Android is based around Android Service
components (known as "HCE services"). One of the key advantages of a service is that it can run in the background without any user interface. This is a natural fit for many HCE applications like loyalty or transit cards, with which the user shouldn't need to launch the app to use it. Instead, tapping the device against the NFC reader starts the correct service (if not already running) and executes the transaction in the background. Of course, you are free to launch additional UI (such as user notifications) from your service if that makes sense.
Android中的HCE架构基于Android Service
组件(称为“HCE服务”)。服务的一个主要优点是它可以在后台运行而无需任何用户界面。这很适合许多HCE应用程序,如忠诚度[优惠]卡或转接[交通]卡,用户无需启动应用程序即可使用它。相反,在NFC阅读器上点击设备会启动正确的服务(如果尚未运行)并在后台执行事务。当然,如果有意义,您可以自由地从服务中启动其他UI(例如用户通知)。
Service selection
服务选择
When the user taps a device to an NFC reader, the Android system needs to know which HCE service the NFC reader actually wants to talk to. This is where the ISO/IEC 7816-4 specification comes in: it defines a way to select applications, centered around an Application ID (AID). An AID consists of up to 16 bytes. If you are emulating cards for an existing NFC reader infrastructure, the AIDs that those readers are looking for are typically well-known and publicly registered (for example, the AIDs of payment networks such as Visa and MasterCard).
当用户将设备轻敲到NFC读取器时,Android系统需要知道NFC读取器实际想要与哪个HCE服务通信。这就是ISO / IEC 7816-4规范的用武之地:它定义了一种以应用程序ID(AID)为中心选择应用程序的方法。AID最多包含16个字节。如果您要模拟现有NFC读卡器基础设施的卡,那些读者正在寻找的AID通常是众所周知的并且是公开注册的(例如,支付网络的AID,例如Visa和MasterCard)。
If you want to deploy new reader infrastructure for your own application, you will need to register your own AID(s). The registration procedure for AIDs is defined in the ISO/IEC 7816-5 specification. Google recommends registering an AID as per 7816-5 if you are deploying a HCE application for Android, as it will avoid collisions with other applications.
如果要为自己的应用程序部署新的阅读器基础结构,则需要注册自己的AID。AID的注册程序在ISO / IEC 7816-5规范中定义。如果您要为Android部署HCE应用程序,Google建议按照7816-5注册AID,因为这样可以避免与其他应用程序发生冲突。
AID groups
AID组
In some cases, an HCE service may need to register multiple AIDs to implement a certain application, and it needs to be sure that it is the default handler for all of these AIDs (as opposed to some AIDs in the group going to another service).
在某些情况下,HCE服务可能需要注册多个AID来实现某个应用程序,并且需要确保它是所有这些AID的默认处理程序(而不是该组中的某些AID转到另一个服务) 。
An AID group is a list of AIDs that should be considered as belonging together by the OS. For all AIDs in an AID group, Android guarantees one of the following:
AID组是应被视为OS所属的AID列表。对于AID组中的所有AID,Android保证以下其中一项:
- All AIDs in the group are routed to this HCE service
- 组中的所有AID都路由到
此[对应]HCE服务 - No AIDs in the group are routed to this HCE service (for example, because the user preferred another service which requested one or more AIDs in your group as well)
- 组中没有AID被路由到此HCE服务(例如,因为用户更喜欢在您的组中请求一个或多个AID的另一个服务)
In other words, there is no in-between state, where some AIDs in the group can be routed to one HCE service, and some to another.
换句话说,没有中间状态,其中组中的一些AID可以路由到一个HCE服务,一些到另一个。
AID groups and categories
AID组和类别
Each AID group can be associated with a category. This allows Android to group HCE services together by category, and that in turn allows the user to set defaults at the category level instead of the AID level. In general, avoid mentioning AIDs in any user-facing parts of your application: they do not mean anything to the average user.
每个AID组可以与一个类别相关联。这允许Android按类别将HCE服务组合在一起,这反过来允许用户在类别级别而不是AID级别设置默认值。通常,避免在应用程序的任何面向用户的部分中提及AID:它们对普通用户没有任何意义。
Android 4.4 supports two categories: CATEGORY_PAYMENT
(covering industry-standard payment apps) and CATEGORY_OTHER
(for all other HCE apps).
Android 4.4支持两类:( CATEGORY_PAYMENT
涵盖行业标准支付应用)和CATEGORY_OTHER
(适用于所有其他HCE应用)。
Note: Only one AID group in the CATEGORY_PAYMENT
category may be enabled in the system at any given time. Typically, this will be an app that understands major credit card payment protocols and which can work at any merchant.
注意:CATEGORY_PAYMENT
在任何给定时间,系统中只能启用 该类别中的一个AID组。通常情况下,这将是一个了解主要信用卡支付协议的应用程序,可以在任何商家工作。
For closed-loop payment apps that only work at one merchant (such as stored-value cards), you should use CATEGORY_OTHER
. AID groups in this category can be always active, and can be given priority by NFC readers during AID selection if necessary.
对于仅在一个商家(例如储值卡)工作的闭环支付应用,您应该使用CATEGORY_OTHER
。此类别中的AID组可以始终处于活动状态,并且如果需要,可以在AID选择期间由NFC读取器给予优先级。
Implementing an HCE service
实[现]施HCE服务
To emulate an NFC card using host-based card emulation, you need to create a Service
component that handles the NFC transactions.
要使用基于主机的卡仿真模拟NFC卡,您需要创建一个Service
处理NFC事务的组件。
Checking for HCE support
检查HCE支持
Your application can check whether a device supports HCE by checking for the FEATURE_NFC_HOST_CARD_EMULATION
feature. You should use the <uses-feature>
tag in the manifest of your application to declare that your app uses the HCE feature, and whether it is required for the app to function or not.
您的应用程序可以通过检查FEATURE_NFC_HOST_CARD_EMULATION
功能来检查设备是否支持HCE 。您应该使用<uses-feature>
应用程序清单中的 标记来声明您的应用程序使用HCE功能,以及应用程序是否需要运行。
上面这些讲的,是在功能清单文件中,添加下面几个。AndroidManifes.mxl
<!--API 9 设备可以使用近场通信(NFC)进行通信。-->
<!--<uses-feature android:name="android.hardware.nfc" android:required="true">-->
<!--API 19 该设备支持基于主机的NFC卡仿真。-->
<!--<uses-feature android:name="android.hardware.nfc.hcef" android:required="true" />-->
<!--API 24 该设备支持基于主机的NFC-F卡仿真。-->
<!--<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />-->
Service implementation
服务实施
Android 4.4 comes with a convenience Service
class that can be used as a basis for implementing a HCE service: the HostApduService
class.
Android 4.4带有一个便利Service
类,可以作为实现HCE服务的基础:HostApduService
类。
The first step is therefore to extend HostApduService
.
因此,第一步是扩展HostApduService
。
JAVA实现,KOTLIN略。
public class MyHostApduService extends HostApduService {
@Override
public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
...
}
@Override
public void onDeactivated(int reason) {
...
}
}
HostApduService
declares two abstract methods that need to be overridden and implemented.
HostApduService
声明需要重写和实现的两个抽象方法。
processCommandApdu()
is called whenever a NFC reader sends an Application Protocol Data Unit (APDU) to your service. APDUs are defined in the ISO/IEC 7816-4 specification as well. APDUs are the application-level packets being exchanged between the NFC reader and your HCE service. That application-level protocol is half-duplex: the NFC reader will send you a command APDU, and it will wait for you to send a response APDU in return.
processCommandApdu()
只要NFC阅读器向您的服务发送应用程序协议数据单元(APDU),就会调用此方法。APDU也在ISO / IEC 7816-4规范中定义。APDU是NFC读取器和HCE服务之间交换的应用程序级数据包。该应用程序级协议是半双工的:NFC读取器将向您发送命令APDU,它将等待您发送响应APDU作为回报。
Note: The ISO/IEC 7816-4 specification also defines the concept of multiple logical channels, where you can have multiple parallel APDU exchanges on separate logical channels. Android’s HCE implementation however only supports a single logical channel, so there’s only a single-threaded exchange of APDUs.
注: ISO / IEC 7816-4规范还定义了多个逻辑信道的概念,您可以在不同的逻辑信道上进行多个并行APDU交换。然而,Android的HCE实现仅支持单个逻辑通道,因此只有APDU的单线程交换。
As mentioned previously, Android uses the AID to determine which HCE service the reader wants to talk to. Typically, the first APDU an NFC reader sends to your device is a "SELECT AID" APDU; this APDU contains the AID that the reader wants to talk to. Android extracts that AID from the APDU, resolves it to an HCE service, then forwards that APDU to the resolved service.
如前所述,Android使用AID来确定读者想要与之通信的HCE服务。通常,NFC读取器发送到您的设备的第一个APDU是“SELECT AID”APDU; 此APDU包含读者想要与之交谈的AID。Android从APDU中提取该AID,将其解析为HCE服务,然后将该APDU转发到已解析的服务。
You can send a response APDU by returning the bytes of the response APDU from processCommandApdu()
. Note that this method will be called on the main thread of your application, which shouldn't be blocked. So if you can't compute and return a response APDU immediately, return null. You can then do the necessary work on another thread, and use the sendResponseApdu()
method defined in the HostApduService
class to send the response when you are done.
您可以通过返回响应APDU的字节来发送响应APDU processCommandApdu()
。请注意,此方法将在应用程序的主线程上调用,不应阻止。因此,如果您无法立即计算并返回响应APDU,则返回null。然后,您可以在另一个线程上执行必要的工作,并使用类中sendResponseApdu()
定义的方法在完成HostApduService
后发送响应。
Android will keep forwarding new APDUs from the reader to your service, until either:
- The NFC reader sends another "SELECT AID" APDU, which the OS resolves to a different service;
- The NFC link between the NFC reader and your device is broken.
Android将继续从阅读器向您的服务转发新的APDU,直到:
- NFC读取器发送另一个“SELECT AID”APDU,OS解析为另一个服务;
- NFC读卡器与您的设备之间的NFC链接已断开。
In both of these cases, your class's onDeactivated()
implementation is called with an argument indicating which of the two happened.
在这两种情况下,onDeactivated()
都会调用类的 实现,并带有一个参数,指示两者中的哪一个发生了。
If you are working with existing reader infrastructure, you need to implement the existing application-level protocol that the readers expect in your HCE service.
如果您正在使用现有的阅读器基础结构,则需要实现读者期望在HCE服务中使用的现有应用程序级协议。
If you are deploying new reader infrastructure which you control as well, you can define your own protocol and APDU sequence. In general try to limit the amount of APDUs and the size of the data that needs to be exchanged: this makes sure that your users will only have to hold their device over the NFC reader for a short amount of time. A reasonable upper bound is about 1KB of data, which can usually be exchanged within 300ms.
如果您正在部署您控制的新读卡器基础结构,则可以定义自己的协议和APDU序列。通常尝试限制APDU的数量和需要交换的数据的大小:这可以确保您的用户只需要在短时间内将设备放在NFC读取器上。合理的上限是大约1KB的数据,通常可以在300ms内交换。
Service manifest declaration and AID registration
服务清单声明和AID注册
Your service must be declared in the manifest as usual, but some additional pieces must be added to the service declaration as well.
您的服务必须照常在清单中声明,但也必须在服务声明中添加一些其他部分。
First, to tell the platform that it is a HCE service implementing a HostApduService
interface, your service declaration must contain an intent filter for the SERVICE_INTERFACE
action.
首先,要告诉平台它是实现HostApduService
接口的HCE服务 ,您的服务声明必须包含该SERVICE_INTERFACE
操作的intent过滤器。
Additionally, to tell the platform which AIDs groups are requested by this service, a SERVICE_META_DATA
<meta-data>
tag must be included in the declaration of the service, pointing to an XML resource with additional information about the HCE service.
另外,为了告诉平台该服务请求哪些AID组,SERVICE_META_DATA
<meta-data>
必须在服务声明中包含标记,指向具有关于HCE服务的附加信息的XML资源。
Finally, you must set the android:exported
attribute to true, and require the"android.permission.BIND_NFC_SERVICE"
permission in your service declaration. The former ensures that the service can be bound to by external applications. The latter then enforces that only external applications that hold the"android.permission.BIND_NFC_SERVICE"
permission can bind to your service. Since"android.permission.BIND_NFC_SERVICE"
is a system permission, this effectively enforces that only the Android OS can bind to your service.
最后,您必须将该android:exported
属性设置为true,并"android.permission.BIND_NFC_SERVICE"
在服务声明中要求 权限。前者确保服务可以由外部应用程序绑定。然后,后者强制只有拥有"android.permission.BIND_NFC_SERVICE"
权限的外部应用程序 才能绑定到您的服务。由于"android.permission.BIND_NFC_SERVICE"
是系统权限,这有效地强制了只有Android操作系统才能绑定到您的服务。
Here's an example of a HostApduService
manifest declaration:
这是一个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>
This meta-data tag points to an apduservice.xml
file. An example of such a file with a single AID group declaration containing two proprietary AIDs is shown below:
此元数据标记指向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>
The <host-apdu-service>
tag is required to contain a <android:description>
attribute that contains a user-friendly description of the service that may be shown in UI. The requireDeviceUnlock
attribute can be used to specify that the device must be unlocked before this service can be invoked to handle APDUs.
<host-apdu-service>
标签需要包含一个<android:description>
包含了可在用户界面中显示的服务的用户友好的描述属性。该requireDeviceUnlock
属性可用于指定在调用此服务以处理APDU之前必须解锁设备。
The <host-apdu-service>
must contain one or more <aid-group>
tags. Each <aid-group>
tag is required to:
- Contain an
android:description
attribute that contains a user-friendly description of the AID group, suitable for display in UI. - Have its
android:category
attribute set to indicate the category the AID group belongs to, e.g. the string constants defined byCATEGORY_PAYMENT
orCATEGORY_OTHER
. - Each
<aid-group>
must contain one or more<aid-filter>
tags, each of which contains a single AID. The AID must be specified in hexadecimal format, and contain an even number of characters.
在<host-apdu-service>
必须包含一个或多个<aid-group>
标签。每个 <aid-group>
标签都需要:
- 包含一个
android:description
属性,该属性包含AID组的用户友好描述,适合在UI中显示。 android:category
设置其属性以指示AID组所属的类别,例如由CATEGORY_PAYMENT
或定义的字符串常量CATEGORY_OTHER
。- 每个
<aid-group>
必须包含一个或多个<aid-filter>
标签,每个标签包含一个AID。AID必须以十六进制格式指定,并包含偶数个字符。
As a final note, your application also needs to hold the NFC
permission to be able to register as a HCE service.
最后,您的应用程序还需要拥有NFC
能够注册为HCE服务的 权限。
AID conflict resolution
AID冲突解决方案
Multiple HostApduService
components may be installed on a single device, and the same AID can be registered by more than one service. The Android platform resolves AID conflicts depending on which category an AID belongs to. Each category may have a different conflict resolution policy.
多个HostApduService
组件可以在单个设备上安装,并且可以通过多个服务注册相同的AID。Android平台根据AID所属的类别解决AID冲突。每个类别可能有不同的冲突解决策略。
For example, for some categories (like payment) the user may be able to select a default service in the Android settings UI. For other categories, the policy may be to always ask the user which service is to be invoked in case of conflict. To query the conflict resolution policy for a certain category, see getSelectionModeForCategory()
.
例如,对于某些类别(如支付),用户可能能够在Android设置UI中选择默认服务。对于其他类别,策略可以是始终询问用户在发生冲突时要调用哪个服务。要查询特定类别的冲突解决策略,请参阅 getSelectionModeForCategory()
。
Check if your service is the default
检查您的服务是否是默认服务
Applications can check whether their HCE service is the default service for a certain category by using theisDefaultServiceForCategory(ComponentName, String)
API.
应用程序可以使用isDefaultServiceForCategory(ComponentName, String)
API 检查其HCE服务是否是特定类别的默认服务 。
If your service is not the default, you can request it to be made the default. See ACTION_CHANGE_DEFAULT
.
如果您的服务不是默认服务,则可以请求将其设为默认服务。见ACTION_CHANGE_DEFAULT
。
Payment applications
付款申请
Android considers HCE services that have declared an AID group with the "payment" category as payment applications. The Android 4.4 release contains a top-level Settings menu entry called "tap & pay", which enumerates all such payment applications. In this settings menu, the user can select the default payment application that will be invoked when a payment terminal is tapped.
Android将已声明具有“付款”类别的AID组的HCE服务视为支付应用程序。Android 4.4版本包含一个名为“tap&pay”的顶级设置菜单条目,其中列举了所有此类支付应用程序。在此设置菜单中,用户可以选择在点击支付终端时将调用的默认支付应用程序。
Required assets for payment applications
支付应用程序所需的资产
To provide a more visually attractive user experience, HCE payment applications are required to provide an additional asset for their service: a so-called service banner.
为了提供更具视觉吸引力的用户体验,HCE支付应用程序需要为其服务提供额外资产:所谓的服务横幅。
This asset should be sized 260x96 dp, and can be specified in your meta-data XML file by adding the android:apduServiceBanner
attribute to the <host-apdu-service>
tag, which points to the drawable resource. An example is shown below:
此资产的大小应为260x96 dp,并且可以通过向标记添加android:apduServiceBanner
属性来指定元数据XML文件,该<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
屏幕关闭和锁屏行为
Current Android implementations turn the NFC controller and the application processor off completely when the screen of the device is turned off. HCE services will therefore not work when the screen is off.
当设备的屏幕关闭时,当前的Android实现完全关闭NFC控制器和应用程序处理器。因此,当屏幕关闭时,HCE服务将不起作用。
HCE services can function from the lock-screen however: this is controlled by the android:requireDeviceUnlock
attribute in the <host-apdu-service>
tag of your HCE service. By default, device unlock is not required, and your service will be invoked even if the device is locked.
然而,HCE服务可以从锁定屏幕运行:这由HCE服务android:requireDeviceUnlock
的<host-apdu-service>
标签中的属性控制。默认情况下,不需要设备解锁,即使设备已锁定,也会调用您的服务。
If you set the android:requireDeviceUnlock
attribute to "true" for your HCE service, Android will prompt the user to unlock the device when you tap an NFC reader that selects an AID that is resolved to your service. After unlocking, Android will show a dialog prompting the user to tap again to complete the transaction. This is necessary because the user may have moved the device away from the NFC reader in order to unlock it.
如果您android:requireDeviceUnlock
为HCE服务将属性设置为“true”,则当您点击选择已解析为您的服务的AID的NFC阅读器时,Android将提示用户解锁设备。解锁后,Android将显示一个对话框,提示用户再次点按以完成交易。这是必要的,因为用户可能已经将设备从NFC读取器移开以便解锁它。
Coexistence with secure element cards
与安全元素卡共存
This section is of interest for developers that have deployed an application that relies on a secure element for card emulation. Android's HCE implementation is designed to work in parallel with other methods of implementing card emulation, including the use of secure elements.
对于部署了依赖于卡仿真的安全元素的应用程序的开发人员而言,此部分很有用。Android的HCE实现旨在与其他实现卡仿真的方法并行工作,包括使用安全元素。
Note: Android does not offer APIs for directly communicating with a secure element itself.
注意: Android不提供用于直接与安全元素本身通信的API。
This coexistence is based on a principle called "AID routing": the NFC controller keeps a routing table that consists of a (finite) list of routing rules. Each routing rule contains an AID and a destination. The destination can either be the host CPU (where Android apps are running), or a connected secure element.
这种共存基于称为“AID路由”的原理:NFC控制器保留由(有限的)路由规则列表组成的路由表。每个路由规则都包含AID和目标。目标可以是主机CPU(运行Android应用程序的位置),也可以是连接的安全元素。
When the NFC reader sends an APDU with a "SELECT AID", the NFC controller parses it and checks whether the AIDs matches with any AID in its routing table. If it matches, that APDU and all APDUs following it will be sent to the destination associated with the AID, until another "SELECT AID" APDU is received or the NFC link is broken.
当NFC读取器发送具有“SELECT AID”的APDU时,NFC控制器解析它并检查AID是否与其路由表中的任何AID匹配。如果匹配,则APDU及其后面的所有APDU将被发送到与AID相关联的目的地,直到接收到另一个“SELECT AID”APDU或NFC链路中断。
Note: While ISO/IEC 7816-4 defines the concept of “partial matches” as well, this is currently not supported by Android HCE devices.
This architecture is illustrated in figure 4.
注意: 虽然ISO / IEC 7816-4也定义了“部分匹配”的概念,但Android HCE设备目前不支持此功能。
该架构如图4所示。
Figure 4. Android operating with both secure element and host-card emulation.
图4.使用安全元素和主机卡仿真的Android操作。
The NFC controller typically also contains a default route for APDUs. When an AID is not found in the routing table, the default route is used. While this setting might different from device to device, Android devices are required to ensure that the AIDs being registered by your app are properly routed to the host.
Android applications that implement a HCE service or that use a secure element don't have to worry about configuring the routing table - that is taking care of by Android automatically. Android merely needs to know which AIDs can be handled by HCE services and which ones can be handled by the secure element. Based on which services are installed and which the user has configured as preferred, the routing table is configured automatically.
We've already described how to declare AIDs for HCE services. The following section explains how to declare AIDs for applications that use a secure element for card emulation.
NFC控制器通常还包含APDU的默认路由。如果在路由表中找不到AID,则使用默认路由。虽然此设置可能因设备而异,但Android设备需要确保应用注册的AID正确路由到主机。
实现HCE服务或使用安全元素的Android应用程序不必担心配置路由表 - 这是由Android自动处理的。Android只需要知道哪些AID可以由HCE服务处理,哪些可以由安全元素处理。根据安装的服务以及用户已将其配置为首选服务,将自动配置路由表。
我们已经描述了如何为HCE服务声明AID。以下部分说明如何为使用安全元素进行卡仿真的应用程序声明AID。
Secure element AID registration
安全元素AID注册
Applications using a secure element for card emulation can declare a so-called "off host service" in their manifest. The declaration of such a service is almost identical to the declaration of a HCE service. The exceptions are:
- The action used in the intent-filter must be set to
SERVICE_INTERFACE
. - The meta-data name attribute must be set to
SERVICE_META_DATA
. -
The meta-data XML file must use the
<offhost-apdu-service>
root tag.
使用安全元素进行卡仿真的应用程序可以在其清单中声明所谓的“关闭主机服务”。此类服务的声明几乎与HCE服务的声明相同。例外情况是:
- 必须将intent-filter中使用的操作设置为
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>
An example of the corresponding apduservice.xml
file registering two AIDs:
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>
The android:requireDeviceUnlock
attribute does not apply to off host services, because the host CPU is not involved in the transaction and therefore cannot prevent the secure element from executing transactions when the device is locked.
The android:apduServiceBanner
attribute must be used for off host services that are payment applications as well in order to be selectable as a default payment application.
该android:requireDeviceUnlock
属性不适用于关闭主机服务,因为主机CPU不参与事务,因此无法阻止安全元件在设备锁定时执行事务。
该android:apduServiceBanner
属性必须用于支付应用程序的关闭主机服务,以便可选择作为默认支付应用程序。
Off host service invocation
关闭主机服务调用
Android itself will never start or bind to a service that is declared as "off host". This is because the actual transactions are executed by the secure element and not by the Android service itself. The service declaration merely allows applications to register AIDs present on the secure element.
Android本身永远不会启动或绑定到声明为“off host”的服务。这是因为实际的事务是由安全元素执行的,而不是由Android服务本身执行的。服务声明仅允许应用程序注册安全元素上存在的AID。
HCE and security
HCE和安全
The HCE architecture itself provides one core piece of security: because your service is protected by the BIND_NFC_SERVICE
system permission, only the OS can bind to and communicate with your service. This ensures that any APDU you receive is actually an APDU that was received by the OS from the NFC controller, and that any APDU you send back will only go to the OS, which in turn directly forwards the APDUs to the NFC controller.
The core remaining piece is where you get your data that your app sends to the NFC reader. This is intentionally decoupled in the HCE design: it does not care where the data comes from, it just makes sure that it is safely transported to the NFC controller and out to the NFC reader.
For securely storing and retrieving the data that you want to send from your HCE service, you can, for example, rely on the Android Application Sandbox, which isolates your app's data from other apps. For more details on Android security, readSecurity Tips.
HCE体系结构本身提供了一个核心安全性:因为您的服务受BIND_NFC_SERVICE
系统权限保护,所以只有操作系统可以绑定到您的服务并与之通信。这可确保您收到的任何APDU实际上是操作系统从NFC控制器接收的APDU,并且您发回的任何APDU将仅转发到操作系统,而操作系统又直接将APDU转发到NFC控制器。
剩下的核心部分是您获取应用程序发送给NFC阅读器的数据。这在HCE设计中有意去耦:它不关心数据来自何处,它只是确保它被安全地传输到NFC控制器并输出到NFC读取器。
例如,为了安全地存储和检索要从HCE服务发送的数据,您可以依赖Android应用程序沙箱,它将您的应用程序数据与其他应用程序隔离开来。有关Android安全性的更多详细信息,请阅读 安全提示。
Protocol parameters and details
协议参数和细节
This section is of interest for developers that want to understand what protocol parameters HCE devices use during the anti-collision and activation phases of the NFC protocols. This allows building a reader infrastructure that is compatible with Android HCE devices.
对于希望了解HCE设备在NFC协议的防冲突和激活阶段使用的协议参数的开发人员而言,此部分很有用。这允许构建与Android HCE设备兼容的读取器基础结构。
Nfc-A (ISO/IEC 14443 type A) protocol anti-collision and activation
Nfc-A(ISO / IEC 14443 A型)协议防冲突和激活
As part of the Nfc-A protocol activation, multiple frames are exchanged.
In the first part of the exchange the HCE device will present its UID; HCE devices should be assumed to have a random UID. This means that on every tap, the UID that is presented to the reader will be a randomly generated UID. Because of this, NFC readers should not depend on the UID of HCE devices as a form of authentication or identification.
The NFC reader can subsequently select the HCE device by sending a SEL_REQ command. The SEL_RES response of the HCE device will at least have the 6th bit (0x20) set, indicating that the device supports ISO-DEP. Note that other bits in the SEL_RES may be set as well, indicating for example support for the NFC-DEP (p2p) protocol. Since other bits may be set, readers wanting to interact with HCE devices should explicitly check for the 6th bit only, and not compare the complete SEL_RES with a value of 0x20.
作为Nfc-A协议激活的一部分,交换多个帧。
在交换的第一部分,HCE设备将呈现其UID; 应假设HCE设备具有随机UID。这意味着在每次点击时,呈现给阅读器的UID将是随机生成的UID。因此,NFC读取器不应该依赖于HCE设备的UID作为认证或识别的形式。
随后,NFC读取器可以通过发送SEL_REQ命令来选择HCE设备。HCE设备的SEL_RES响应将至少设置第6位(0x20),表示设备支持ISO-DEP。注意,也可以设置SEL_RES中的其他位,指示例如对NFC-DEP(p2p)协议的支持。由于可以设置其他位,想要与HCE设备交互的读者应该明确检查第6位,并且不要将完整的SEL_RES与值0x20进行比较。
ISO-DEP activation
ISO-DEP激活
After the Nfc-A protocol is activated, the ISO-DEP protocol activation is initiated by the NFC reader. It sends a "RATS" (Request for Answer To Select) command. The RATS response, the ATS, is completely generated by the NFC controller and not configurable by HCE services. However, HCE implementations are required to meet NFC Forum requirements for the ATS response, so NFC readers can count on these parameters being set in accordance with NFC Forum requirements for any HCE device.
激活Nfc-A协议后,NFC读取器启动ISO-DEP协议激活。它发送“RATS”(请求应答选择)命令。RATS响应ATS完全由NFC控制器生成,不能由HCE服务配置。但是,HCE实施需要满足NFC论坛对ATS响应的要求,因此NFC读取器可以依赖于根据NFC论坛对任何HCE设备的要求设置这些参数。
The section below provides more details on the individual bytes of the ATS response provided by the NFC controller on a HCE device:
以下部分提供了有关HCE设备上NFC控制器提供的ATS响应的各个字节的更多详细信息:
- TL: length of the ATS response. Must not indicate a length greater than 20 bytes.
- T0: bits 5, 6 and 7 must be set on all HCE devices, indicating TA(1), TB(1) and TC(1) are included in the ATS response. Bits 1 to 4 indicate the FSCI, coding the maximum frame size. On HCE devices the value of FSCI must be between 0h and 8h.
- T(A)1: defines bitrates between reader and emulator, and whether they can be asymmetric. There are no bitrate requirements or guarantees for HCE devices.
- T(B)1: bits 1 to 4 indicate the Start-up Frame Guard time Integer (SFGI). On HCE devices, SFGI must be <= 8h. Bits 5 to 8 indicate the Frame Waiting time Integer (FWI) and codes the Frame Waiting Time (FWT). On HCE devices, FWI must be <= 8h.
- T(C)1: bit 5 indicates support for "Advanced Protocol features". HCE devices may or may not support "Advanced Protocol features". Bit 2 indicates support for DID. HCE devices may or may not support DID. Bit 1 indicates support for NAD. HCE devices must not support NAD and set bit 1 to zero.
- Historical bytes: HCE devices may return up to 15 historical bytes. NFC readers willing to interact with HCE services should make no assumptions about the contents of the historical bytes or their presence.
- TL:ATS响应的长度。不得指示长度大于20个字节。
- T0:必须在所有HCE设备上设置第5,6和7位,表示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必须<= 8h。位5到8指示帧等待时间整数(FWI)并编码帧等待时间(FWT)。在HCE设备上,FWI必须<= 8h。
- T(C)1:位5表示支持“高级协议功能”。HCE设备可能支持也可能不支持“高级协议功能”。位2表示支持DID。HCE设备可能支持也可能不支持DID。位1表示支持NAD。HCE设备不得支持NAD并将第1位设置为零。
- 历史字节:HCE设备最多可返回15个历史字节。愿意与HCE服务交互的NFC读者不应对历史字节的内容或它们的存在做出任何假设。
Note that many HCE devices are likely made compliant with protocol requirements that the payment networks united in EMVCo have specified in their "Contactless Communication Protocol" specification. In particular:
请注意,许多HCE设备可能符合协议要求,EMVCo中的支付网络已在其“非接触式通信协议”规范中指定。特别是:
- T0中的FSCI必须在2h到8h之间。
- T(A)1必须设置为0x80,表示仅支持106 kbit / s比特率,并且不支持读取器和仿真器之间的非对称比特率。
- T(B)1中的FWI必须<= 7h。
- FSCI in T0 must be between 2h and 8h.
- T(A)1 must be set to 0x80, indicating only the 106 kbit/s bitrate is supported, and asymmetric bitrates between reader and emulator are not supported.
- FWI in T(B)1 must be <= 7h.
APDU data exchange
APDU数据交换
As noted earlier, HCE implementations only support a single logical channel. Attempting to select applications on different logical channels will not work on a HCE device.
如前所述,HCE实现仅支持单个逻辑信道。尝试在不同逻辑信道上选择应用程序将无法在HCE设备上运行。
扫码关注微信,不定期用心推送优质文章。
【Java开发交流】(群号157529282),欢迎,有志同道合的朋友加入,交流讨论。