Host

您所在的位置:网站首页 HCE支付怎样取消 Host

Host

2024-05-17 07:40| 来源: 网络整理| 查看: 265

Host-based Card Emulation(基于host的卡模拟)

建议先阅读下面的文章了解卡模拟,卡模拟se技术,卡模拟的hce技术,nfc支付对nfc的卡模式有了初步的了解再来看这篇文章:

知乎:nfc HCE技术介绍

HCE技术和SE技术对比

nfc支付和微信/支付宝支付和信用卡支付的对比

nfc Hce资料汇总

官方demo:nfcCardReader/nfcCardEmulation

许多Android设备提供了nfc卡模拟的nfc功能,大多数情况,nfc卡模拟是通过设备中的一个独立芯片实现的,这个独立芯片被称为Secure Element(安全部分下面都是以se简称)。许多sim卡在提供无线连接的同时提供了这个芯片(se芯片内置到sim卡中是现在比较多用的方式)

Android4.4介绍了一种额外的不需要se的卡模拟方法。被称为Host-baesd card emulation(基于host实现的卡模拟,后面都是以HCE简称)。这个允许任何一个Android应用程序去模拟卡和直接和NFC读卡器通信。这篇文档描述了hce在Android系统上怎样工作的和通过这项技术你可以开发一个模拟nfc卡的app。

使用se模块的卡模拟

基于se模块的nfc卡片模拟方式,卡模拟的逻辑通过Android应用程序预置到设备的se模块(se模块是独立于os的一个单独芯片,可以和os交互,当前常见是内置在sim卡上)中。当用户持有支持nfc终端的设备的时候,设备中的nfc controller(nfc控制器)会把来自card Reader的所有信息都传递给se模块,即:

se模块直接和nfc终端交互,中间不包含任何的Android应用程序,交易结束后,Android应用程序直接查询se模块将最终的交易结果呈现给用户。

hce卡模拟

hce卡模拟,nfc controller将card reader的信息直接给运行Android app的host cpu而不是传递给se模块。即:

综上:se模块的卡模拟是将模拟卡的逻辑交给了独立于os的硬件去处理,而hce技术则是用软件的形式模拟了se模块来处理模拟卡的操作,对其对比如下:

支持的nfc卡和协议

nfc标准对很多不同的协议提供了支持,不同种类的卡片可以被模拟

Android4.4支持当前市场上通用的几个协议,一些存在的非触点卡片和当今市场上的一些读卡器也是支持这些协议(协议想通所以才可以模拟卡的交易)比如非触点支付卡(信用卡储蓄卡等芯片卡),, 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.

特殊的是,Android4.4支持卡的模拟是基于NFC-Forum ISO-DEP 规范(基于 ISO/IEC 14443-4)和process Application Protocol Data Units (处理应用协议数据单元简称APDUs) 基于ISO/IEC 7816-4 规范。ISO_DEP规范是在 Nfc-A (ISO/IEC 14443-3 Type A)基础之上,部分支持(ISO/IEC 14443-4 Type B)技术协议。协议栈的层级结构如下:

HCE service(hce 服务)

hce架构是基于Android service组件实现的(HCE services),service的主要优势是可以无需任何用户UI和接口在后台运行。这也符合许多hceapp(积分卡和过境卡)的需求,用户交易的时候没有必要登录app去使用它,相反当设备和nfc Reader紧密的靠近在一起的时候启动合适的服务(如果服务没有启动)在后台执行交易即可。当然,在交易的时候也可以为后台的服务添加额外的UI(交易详情和交易结果通知等)。

选择服务(service selection)

当设备和nfc读卡器交互的时候,Android系统需要知道nfc读卡器想要和哪一个hce service进行通信。ISO/IEC 7816-4规范提供了选择方式:通过在app中声明application id(AID)的方式选择hce service。aid最高有16个字节构成,如果对当前已经存在的nfc读卡器架构进行卡的模拟,当前已经存在的读卡器支持的Aids都是众所周知和公共注册的(比如:网上支付机构visa和mastercard的aid等都是备案的,直接使用即可)

如果你想为你自己的app开发一个新的读卡架构,需要注册自己的aid。注册aid的方式在ISO/IEC 7816-5规范中声明。开发Android HCE app注册新的AIDAndroid推荐依据ISO/IEC 7816-5规范来注册防止和其他的app的AID冲突。

AID Groups(AID组)

在有些时候,在app中一个HCE 服务需要注册多个aid来确保在这些aids的处理app中自己是默认的处理app(尽可能的防止处理这些aids进入其他的服务)。

aid组是被os认可的aid的集合,对于aid组中的所有aid,Android保证下面的一个:

符合组中所有的aid的被路由到这个服务中

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也被路由到这个服务中和上面冲突?我理解的意思应该是Android系统根据aid组中声明的nfc读卡器声明的aid数量来匹配的,匹配到匹配aid数量多的服务中去)。

换句话说,没有中间态,组中的一些aid被路由到一个hce服务一些被路由到另外的服务。

aid组和类别

每一个aid组都可以关联类别,这样允许Android通过类别区分hce服务,反过来说允许用户通过设置默认的类别的级别来替代aid级别。一般来说在普通用户级别是没有必要提及aid的,aid对于普通用户来说是没有意义的。

Android4.4支持两种类别:CATEGORY_PAYMENT (覆盖支付app行业标准) and CATEGORY_OTHER (其他类型app).

注意: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. 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.(理解不是太深,暂不翻译,意思应该是支付的aid组中aid是固定的,只有一个支付服务响应,或默认或用户选择)

附加aid的匹配策略

参考下面几篇文章总结aid组和类别的匹配:

AID选择策略测试

HCE服务设置默认支付程序

同为支付类型的hce服务,设置默认支付后只有默认支付服务响应,其他一概不响应,没有设置默认服务的时候弹出所有的支付服务供选择

支付类型和other类型的aid组中相同的aid,支付类型的服务优先选择。

同为other类型,aid不同选择不同的服务,aid相同时系统提供app选择,供用户选择处理

实现HCE

为了模拟使用基于host卡模拟技术的nfc卡片,你需要创建一个处理nfc数据的service组件。

检测设备对hce的支持

你的app应该通过检测 FEATURE_NFC_HOST_CARD_EMULATION功能来监测设备对nfc hce的支持。如果hce是你的app的核心功能还需要在你的app的manifest上使用标签来声明你的app需要请求hce功能。

实现服务

Android4.4系统提供了一个对HCE服务有了基本实现的service类叫做HostApduService类。

继承HostApduService类,实现父类定义的抽象类,即:

HostApduService类声明了两个需要重写和实现的抽象子方法,即:

processCommandApdu()方法在nfc读卡器发送apdu数据到你的服务的时候回调,APDU数据格式是ISO/IEC 7816-4规范定义的格式,APDU是nfc设备和HCE服务之间交互的应用程序级别的包。程序级的协议是双向的,Nfc读卡器发送你一个APDU命令,同时一直在等待着你的响应APDU数据。

注意:ISO/IEC 7816-4规范也定义了多逻辑通道的概念,你可以在独立的逻辑通道中多重平行(单通道串行数据交换)的apdu数据交换(多线程)。但是Android的hce服务仅仅支持单逻辑通道,因此他们只是在单个线程里面交换数据。

前面提到过,Android使用AID来决定哪一个hce服务同nfc读卡器交互,所以nfc读卡器发送给你的设备的第一条apdu数据是选择aid APDU数据。这条APDU数据包含的AID就是nfc读卡器想要交互的hce service。Android系统从APDU数据中抽取这个aid并通过aid选取恰当的hce service。

你可以通过processCommandApdu()方法返回的APDU响应字节数组作为APDU的响应。注意这个方法是在app的主线程调用的所以不能够阻断,因此在这个方法里不能够做复杂的操作和耗时计算,如果有这些需要可以在方法中返回一个null,然后另起一个线程去计算或者做耗时操作,计算完成后通过HostApduService类中的方法 sendResponseApdu()) 发送响应给读卡器。

Android将持续的发送来自nfc Reader的新的apdu数据到你的service,直到下面情形发生:

NFC 读卡器发送了另一个“select AID”apdu数据选取了另外一个服务处理。

nfc读卡器和Android设备之间的连接通道断开。

上面这两种情形,HostApduService类中的方法onDeactivated()将会被回调。

如果你想和当前已存在的读卡器交互,在你的hce服务中实现读卡器期望的当前已经存在的程序级协议和APDU架构即可。

如果你想开发一套新的自己控制的读卡器架构,你需要定义你的私有协议和apdu数据架构。由于设备和读卡器接触的时间极短,所以限制apdu数据交互次数和限制数据传输的大小是很有必要的。一次扫描通常传输1k数据,300ms的时间。

manifest文件声明service和注册AID

你的service需要像往常那样在manifest文件中声明,不同的是需要添加一些额外的标签。

首先需要告诉平台这是一个实现了HostApduService的HCE service。你的service声明必须包含SERVICE_INTERFACE action的intentfilter的声明。

其次,告诉平台被这个服务处理的AID组,SERVICE_META_DATA 必须包含在service的声明中。指向一个关于这个hce service 额外信息的xml资源。

最后:你必须设置android:exported为true和在服务声明中请求android.permission.BIND_NFC_SERVICE权限。这个设置确保了服务可以被外面的app启动。android.permission.BIND_NFC_SERVICE是一个系统权限,声明这个权限表明只有Android系统可以绑定你的服务。

下面是HostApduService的manifest声明案例:

meta-data标签指向一个 apduservice.xml 文件。下面是一个声明AID组的apduservice.xml文件事例:

标签的属性描述了服务的用户级别友好的描述。requireDeviceUnlock属性指定了Android设备锁屏的时候是否可以后台处理apdu数据。

标签必须包含一个或者多个标签,每一个aid标签都需要包含下面的属性:

android:description :关于这个AID组的友好描述,包括上面的描述有可能在UI中体现。

android:category :指定aid组的类别,关于类别上面有叙述。

每一个标签必须包含一个或多个标签,每一个filter都包含一个单独的AID,AID格式必须是16进制的格式包含最多16个字节(下面是16进制字节数组和string之间的转换:)。

还有你的app还要申请nfc的权限。

AID冲突解决

在一个设备上可能安装有多个 HostApduService组件,相同的AID在一个设备上也可能注册多次。Android平台解决AID冲突依赖于AID组的类别归属,不同的类别归属有着不同的冲突解决策略。

例如:支付类的的策略是需要用户在系统设置页面选择一个默认的服务。其他类别的在AID冲突的时候是需要弹出所有的服务交给用户去选择处理。通过类CardEmulation(下面有介绍)中的api(getSelectionModeForCategory()))可以查询到该类别模拟卡的aid冲突策略。

检查你的服务是不是默认服务

Android系统提供了检查自己的服务是不是某个AId的默认处理服务的api(isDefaultServiceForAid()还是在cardemulation类中的一个api)

如果你的服务不是默认的,你可以请求设置它为默认的,具体参考ACTION_CHANGE_DEFAULT

附加:Cardemulation的介绍

cardemulation:用来查询NFC 模拟卡服务的状态的类,是一个单例类,通过api(getinstanse(nfcadapter nfcadapter))可以获得类的实例对象,通过此实例对象可以查询当前服务的状态和aid冲突的解决策略等。

支付应用程序

Android 认定声明AID组的类别为"payment"的HCE service为支付应用程序,Android4.4在顶级设置目录里面包含一个叫“tap&pay”的选项,里面例举了所有的支付应用程序。在这个设置目录里面,用户可以选择默认的支付应用程序在支付终端交互的时候被唤醒处理支付交易。

为支付程序设置资源

为了提供更好的用户体验,HCE支付应用程序需要为他们的服务提供一个额外的asset,被称作service banner。

这个asset的大小是260*96dp(具体的对应关系在demo中的注释中有写)在xml资源的标签属性android:apduServiceBanner添加,指向一个drawable的资源文件,设置如下:

锁屏行为

当设备的屏幕关闭(锁屏)的时候Android实现了nfc controller和app进程完全关闭(断开),所以Hce服务在设备屏幕锁屏后不在工作(hce服务的过程中锁屏服务停止)。

然而hce服务在锁屏状态是否服务取决于xml文件 的声明的android:requireDeviceUnlock 属性。默认值是false,即设备锁屏状态下你的服务仍然运行。

如果你设置android:requireDeviceUnlock 值为true,在你的设备接近nfc读卡器并通过aid选中你的服务时候Android设备会提示你解锁,在你解锁后会有一个dialog告诉你重新靠近读卡器进行支付。由于你的解锁行为需要远离读卡器(断开了链接通道)所以这样处理是很有用的。

兼容基于se的卡模拟

对于基于se模块的卡模拟已经开发应用程序的开发者对这一片段比较感兴趣。Android的Hce实现是兼容其他方式实现的卡模拟的,包括基于se模块的卡模拟。

注意:Android并没有提供api和se模块直接通信。

这个兼容是基于AID路由的原理:nfc controller持有一个由路由规则集合构成的aid路由表。每一条路由规则包含一个aid和一个定义,这个定义描述了是把数据给hce host还是把数据传递给se模块。

当nfc读卡器发送带有“select aid”的APDU数据时,nfc controller会解析这条数据并检测在持有的路由表中是否有AID与其匹配,如果匹配,这条数据及其后续的apdu数据都会发送到与aid关联的目的地去。直到下一个aid选择或者通道断开连接。

注意:ISO/IEC 7816-4规范还定义了一种局部匹配的概念,但是Android系统并不支持。

下面是hce服务对se模块和hce两者支持的架构图:

nfc controller还包含一个默认的apdu数据的路由,当aid在持有的aid 路由表中没有匹配的时候使用。默认aid路由在设备间是不相同的。Android设被确保注测到你的app的aid都能精确到路由到host。

基于host实现还是基于se实现都不用担心路由表的配置,路由表的配置是Android系统自动配置的。Android系统仅仅需要知道aid是由host处理还是se模块处理即可。这个通过service被安装的时候的配置文件xml的配置即可。

我们已经描述了hce service的配置。下面的片段解释了基于se模块的卡模拟设置如何配置:

基于se模块的aid注册

使用se模块模拟卡的app需要在manifest文件声明“offhostservice”,改服务的声明和HCE服务的声明很相似,规则如下:

intent-filter的action使用必须设置成为SERVICE_INTERFACE.

meta-data的属性名必须设置成SERVICE_META_DATA.

meta-dataxml文件必须使用 根标签。即:

相应的带有AID的apduservice.xml的声明如下:

对于offhostservice来说 android:requireDeviceUnlock属性并不需要申请的,因为在基于se模块的卡模拟的交易并不依赖于host cpu,即时设备在锁定的状态也不妨碍基于se模块的卡模拟交易。

对于offhostservice来说 android:apduServiceBanner属性也是需要的,设置后可以方便用户来选择默认的支付程序。(这个属性是指定一个图片用来显示支付类型,图片的像素设置可以参考demo,demo的注释里面有着详细的配置)

off host service invocation(se 模块service调用)

Android系统本身并不启动和绑定off host service,因为基于se模块的卡模拟的交易并不是在Android系统中,而是基于se模块。这个服务的声明仅仅是允许注册aids来代表se模块(主要实现aid路由表的功能)

HCE和安全

HCE架构本身提供了一种核心的安全模块。因为你的服务收到系统权限BIND_NFC_SERVICE的保护。仅仅系统可以绑定服务和服务通信。这样就保证了你的service接收到的任何apdu数据仅仅是被o从nfccontrollers接收到。你发送的apdu数据也是发送给os然后os直接数据返还给nfc controller。

在你的服务中获取到你需要发送给nfc读卡器的数据和hce设计是没有关联的。并不关心数据来自那里,hce的设计主要是保证nfc controller和service还有nfc controller和nfc reader之间的数据传输安全。

为了安全发送你想发送和接受来自于hceservice的数据,你可以在service中做一些安全的措施,比如Android的沙盒环境。这样就把自己app的数据和其他app的数据隔离。了解更多的信息可以参考Security Tips

附加一点自己的理解:基于se模块的安全性能肯定要比hce服务更全更高一些。毕竟系统权限的保护对于没有root和刷机的还好一些,Android的开源性决定了Android系统的安全度不高。还有初步猜测apple pay应该是基于se模块(se模块在终端)或者hce服务实现的(ios的闭源决定其安全性能相对的高),se模块是独立于os的,交易都是在单独的芯片上实现。

协议参数和详情

对这个片段感兴趣的开发者想要理解HCE服务在解决冲突时的协议参数和nfc激活解析协议。这些协议允许组建一个Android nfc兼容的读卡器架构。

NFC-A协议解决冲突和激活 ISO-DEP activivation

涉及到的协议和数据解析多是针对读卡器的,在app上使用不多,需要时可以直接参考文档和具体的文档(文档只是简要的说明并没有深入,如果想深入理解可以去nfc组织架构下载具体的协议深入理解)

apdu数据交换

简单的记录一下:HCE的实现仅仅支持单逻辑通道,多逻辑通道交换apdu数据在Android上不支持



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3