Android Host-based Card Emulation

译自 https://developer.android.google.cn/guide/topics/connectivity/nfc/hce.html

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.

Android 4.4引入了一个新加的方法来模拟卡片,它不会涉及到安全元件,叫做基于主机的卡仿真。它允许任何Android应用模拟卡片,并且直接和NFC读取器交互。该文档描述了基于主机的卡片仿真(HCE)在Android上是如何运行的和如何开发一个app使用该技术来模拟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控制器会将NFC读取器中的所有数据直接路由到安全元件中。图1就表明了这种概念。

这里写图片描述

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 IsoDep class). This allows you to build and deploy an end-to-end NFC solution around HCE using only Android-powered devices.

Android 4.4提供了几个在今天的市面上都是非常常见的协议。许多存在的非接咯也是基于这些协议的,比如非接支付卡。这些协议也被今天市面上的许多NFC读取器所支持,包括Android NFC设备作为的读取器自己(详见 IsoDep 类)。它允许你围绕着HCE仅使用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-Forum ISO-DEP 规格说明书”(基于“ISO/IEC 14443-4”)并且处理定义在“ISO/IEC 7816-4 规格说明书”的应用程序协议数据单元(APDUs)。Android托管模拟的ISO-DEP 仅在 Nfc-A (ISO/IEC 14443-3 Type A) 技术的顶部。支持Nfc-B (ISO/IEC 14443-4 Type B) 技术是可选的。这些规格说明书的层次结构展现在图3中。

这里写图片描述

Figure 3. Android’s HCE protocol stack.
(图3. Android的HCE协议栈)

HCE 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的服务组件的(称为“HCE services”)。服务的主要优势之一是它可以运行在后台而不用任何用户界面。这就很自然的满足了许多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读卡器基础设备模拟卡片,这些读卡器搜索的AIDs通常是总所周知的并且公开注册的(例如,支付网络的AIDs像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。AIDs的注册流程定义在ISO/IEC 7816-5规格说明书中。如果你在为Android开发HCE项目,Google推荐将每一个AID注册成为7816-5的一员,因为它会避免和其它应用发送冲突。

AID groups

(译:应用程序ID组)

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服务可能需要注册多个AIDs来实现一个确定的应用,需要确定的是它是所有的这些AIDs的默认处理器(而不是某些在一个组里将要被加入到其它服务中的AIDs)。

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:

  • All AIDs in the group are routed to this HCE service
  • 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组是一个AIDs的列表,它们应该被系统一起考虑。因为AID组中的所有AIDs,Android都保证下列之一:

  • 所有在一个组的AIDs都会被路由这个HCE服务。
  • 没有一个在该组的AIDs会被路由到这个HCE服务(例如,因为用户倾向于其它服务,它要求在该组的一个或多个AIDs也这样)

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.

换句话说,就是没有中间状态,即在同一个组的一些AIDs被路由到这个HCE服务,另一些被路由到其它服务。

AID groups and categories

(译:应用程序ID组和类别)

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级别。通常来说,避免向你程序的任何面向用户的部分提及AIDs:它们对普通用户来说并没有任何意义。

Android 4.4 supports two categories: CATEGORY_PAYMENT (covering industry-standard payment apps) and CATEGORY_OTHER (for all other HCE apps).

Android 4.4支持2类类别: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

(译:实现一个基于主机的卡片仿真服务)

To emulate an NFC card using host-based card emulation, you need to create a Service component that handles the NFC transactions.

要使用基于主机的卡片仿真来模拟一个NFC卡片,你需要创建一个服务组件来处理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特性。

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 自带了一个非常方便的服务类,它可以作为HCE服务的基类:HostApduService类。

The first step is therefore to extend HostApduService.

因此第一步是继承HostApduService。

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.

但NFC读取器发送一个应用程序协议数据单元到你的服务上时,会调用processCommandApdu()方法。APDUs都被定义在ISO/IEC 7816-4 规格说明书中。APDUs是应用程序级别的包,它可以在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仅支持一个单独的逻辑通道,因此只会单线程地交换APDUs。

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是一个“选择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.

你可以通过processCommandApdu()返回的APDU响应字节,来发送一个APDU响应。注意该方法会被调用在你的应用程序的主线程中,但它不应该被阻塞。因此,如果你不能立即计算出并返回一个APDU响应,返回空。你可以在其它的线程执行那些必要的工作,然后当你完成时,使用HostApduService类中定义的sendResponseApdu()方法来发送响应。

Android will keep forwarding new APDUs from the reader to your service, until either:

  1. The NFC reader sends another “SELECT AID” APDU, which the OS resolves to a different service;
  2. The NFC link between the NFC reader and your device is broken.

Android会从读取器中继续转发新的APDUs到你的服务,直到:

  1. NFC读取器发送了其它“选择AID”的APDU,它被系统解析到另一个不同的服务;
  2. 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 sane upper bound is about 1KB of data, which can usually be exchanged within 300ms.

如果你正在开发一个新的且可控的读取架构,你可以定义你自己的协议和APDU序列。通常,要限制待交换的APDUs数量和数据的大小:可以确定的是用户只会将它们的设备放在NFC读取器上保持很短的时间。一个明智的数据上限是1KB,它通常可以在300ms内完成交换。

Service manifest declaration and AID registration

(译:声明服务清单和注册应用程序ID)

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.

首先,告诉系统某个HCE服务事项了HostApduService接口,你的服务声明必须包含一个SERVICE_INTERFACE 动作的意图过滤器。

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.

另外,告诉系统这个服务需要的是哪一组AIDs,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属性为真,并且在你的服务声明中需要添加”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:

meta-data标签指向了一个apduservice.xml文件。这个仅包含了一个AID组并声明了两个AIDs的文件例子如下:

<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 by CATEGORY_PAYMENT or CATEGORY_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组描述,适合显示在用户界面上。
  • 设置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

(译:应用ID冲突的解决方案)

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的设置界面选择一个默认的服务。其它类别,策略可能是总是询问用户在冲突的情况需要调用哪一个服务。查询一个确定类型的冲突解决方案,参看 getSelectionModeForCategory()

Checking if your service is the default

(译:检查你的服务是否为默认服务)

Applications can check whether their HCE service is the default service for a certain category by using the isDefaultServiceForCategory(ComponentName, String) API.

应用程序可以通过应用程序接口 isDefaultServiceForCategory(ComponentName, String) 来检查它们的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认为使用“payment”声明类型的AID组的HCE服务是支付应用。Android 4.4版本包含了一个顶级的设置菜单,入口叫做“触摸 & 支付”,它枚举了所有这样的支付应用。在该设置菜单中,用户可以选择当触碰到一个支付终端时的默认的支付程序。

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,并且可以指定在你的meta-data XML文件中,通过为<host-apdu-service> 标签添加 android:apduServiceBanner 属性,它指向了图片资源。下面展示一个例子:

<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服务中的<host-apdu-service>标签中的android:requireDeviceUnlock 属性控制的。默认情况下,DeviceUnlock是不需要的,并且即使设备被锁,你的服务也依然会被调用。

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.

如果你为HCE服务将android:requireDeviceUnlock属性设置为“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本身并没有提供APIs来直接与安全元件通信。

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读取器发送一个带“选择 AID”的APDU时,NFC控制器会分析它并且校验是否AIDs符合任何路由表中的AID。如果符合,APDU和所有跟着的APDUs都会被送到与该AID关联的地址上,直到收到其它“选择 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.

注意:ISO/IEC 7816-4 也定义了部分符合的概念,它目前还不被Android HCE 设备所支持。

This architecture is illustrated in figure 4.

该结构在图4中有说明。

这里写图片描述

Figure 4. Android operating with both secure element and host-card emulation.
(译:)图4. Android同时操作安全元件和基于主机的卡片仿真

SoC的全称叫做:System-on-a-Chip,中文的的意思就是“把系统都做在一个芯片上”,如果在PC时代我们说一个电脑的核心是CPU,那么在智能终端时代,手机的核心就是这个SoC。SoC上集成了很多手机上最关键的部件,比如CPU、GPU、内存、也就说虽然它在主板上的存在是一个芯片,但是它里边可是由很多部件封装组成的。

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.

NFC控制器通常也包含一个默认的APDUs路由。当某个AID没有在路由表时,就会使用默认路由。然而这个设置可能不同设备不同,Android设备需要确保被注册到你的应用上的AIDs都是可以恰当路由到其宿主的。

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.

继承了HCE服务或者使用了一个安全元件的Android应用程序不用担心配置路由表的问题 - 这是Android自动会处理的。Android只不过是需要知道哪一个AIDs可以被HCE服务处理和哪一个可以被安全元件处理。基于安装的服务和用户配置的首选项,路由表便会自动配置。

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.

我们已经描述了如何为HCE服务声明AIDs。下面的章节解释了如何为使用安全元件进行卡片仿真的应用程序声明AIDs。

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(OFF_HOST_APDU_SERVICE).
  • 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服务的声明几乎是相同的。例外的是:

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

原文off_host_apdu_service这里少了个s。
这里写图片描述

An example of the corresponding apduservice.xml file registering two AIDs:

一个注册了两个AIDs的对应的apduservice.xml文件的例子:

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

关闭主机服务没有提供android:requireDeviceUnlock 属性,是因为传输中并不涉及主机CPU,因此当设备被锁的时候并不能阻止安全元件执行事务。

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: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服务自己。服务声明仅仅允许应用程序在安全元件上注册AIDs。

HCE and Security

(译:基于主机的卡片仿真和安全)

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.

HCE架构自己提供了一个安全芯片:因为你的服务被系统权限BIND_NFC_SERVICE保护,只有系统可以绑定并与你的服务进行通信。它确保了你收到的任何APDU实际上都是由操作系统从NFC控制器处接收的,并且你回送的任何APDU都只会送给操作系统,接着直接将APDUs再转发给NFC控制器。

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.

在剩余的芯片中,你可以拿到你的应用程序发送给NFC读取器的数据。这是有意地从HCE设计中剥离的:它并不关心数据从哪里来,它只需保证数据可以安全地传递给NFC控制器并发送到NFC读取器。

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, read Security Tips .

为了安全的存储和接收数据,你可能想要从你的HCE服务中发送数据,你可以这样做,例如,依靠Android应用程序沙箱,它可以隔离应用程序之间的数据。更多关于Android系统安全的问题,阅读 Security Tips .

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 type A) 协议的防冲突和激活)

As part of the Nfc-A protocol activation, multiple frames are exchanged.

激活Nfc-A 协议的一部分,多帧交换。

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.

交换的第一阶段,HCE设备会展示出它的UID;HCE设备应该假定获得了一个随机的UID。它意味着每一次的触碰,展示给读取器的UID都会是随机生成的UID,NFC读取器不应该依赖于HCE的UID来作为一种认证或者标识的形式

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读取器随后会通过发送一个 SEL_REQ 命令来选择HCE设备。HCE设备的 SEL_RES 响应至少会设置第6个比特位,来指示设备是否支持ISO-DEP。注意 SEL_RES 的其它比特位也可能被设置,用来指示例如是否支持 NFC-DEP(p2p)协议。因为其它的比特位也可能被设置,所以想要和HCE设备进行互动的读取器就必须明确地校验它的第六位,而不是将整个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:

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

下面的章节提供了关于HCE设备上的NFC控制器提供的ATS响应的个别的位元组更多信息。

  • 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,Start-up Frame Guard time Integer)。在HCE设备上,SFGI必须小于等于8h。第5到8比特指示了帧等待时间(FWI,Frame Waiting time Integer)和编码该帧的等待时间(FWT。Frame waiting Time)。在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:

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

注意许多HCE设备很可能符合EMVCo在它们的“非接通信协议”说明书中规定的支付网络单元的协议。尤其是:

  • T(A)1必须设置为0x80,用来指示仅支持106kbit/s的比特率,不同步的比特率在读取器和模拟器之间是不支持的。
  • FWI 在T(B)1中必须小于等于7h。

APDU data exchange

(译:应用程序数据单元数据交换)

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设备上失效。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值