我们来详细说明一下关于不同模式下的AID响应问题(前提:一个手机,手机上有A、B两个HCE APP,通过读卡器向手机发送APDU选择指令)
1、A和B的应用AID设置的都是payment模式,
只有手机当前选定的默认支付APP会响应,另外一个APP的AID选择指令是不会响应的。
2、A和B的应用AID设置的都是other模式,
当A和B的AID是相同的时候系统会弹出对话框,列出A和B,让用户选择。
如果A和B的AID不同,那么两个APP之间没有相互影响。
3、A和B的应用AID设置的分别是payment(A)和other(B)模式,
如果A和B的AID相同,那么只有A会响应选择指令。
如果A和B的AID不同,那么两者之间不会相互影响
Android 卡模拟(Host-based Card Emulation)。HCE的特点是模拟智能IC卡(ISO 7816-4),可用于金融和行业应用,相应地,CardReader例子中使用IsoDep。
智能IC卡本身是一个微型计算机,常见为Java Card平台,特别是多功能集于一身的卡(如联名卡),Java Card比J2ME更加硬件受限。Java Card可以运行一到多个Java Applet,这些Applet也就是卡应用,例如一张能刷公交的银行卡可能就包含了2个Applet。每个Applet都有一个AID,受理终端(刷卡设备)通过AID来找到对应的卡应用(受理终端向卡发送SELECT命令),受理终端找到对应的卡应用后就可以进行数据交互,交互的数据一般是密文,不联机解密的话,用对称算法,联机解密的话,用非对称和对称算法都行。
HCE是软件模拟的智能IC卡,所以也会有AID。本文CardEmulation只注册一个AID
路由规则
参考文档:NFC 路由表讲解和路由规则梳理.docx
在Android中,nfc数据的处理可能有三种方式:eSE,UICC,HCE。一条nfc数据路由到那种处理方式,是由nfc的路由表来决定的,我们可以通过dumpsys nfc命令查看路由表,如下为mate10的路由表信息(略有删减)
$adb shell dumpsys nfc
mState=off
mIsZeroClickRequested=false
mScreenState=ON_UNLOCKED
mNfcPollingEnabled=false
mNfceeRouteEnabled=false
mOpenEe=null
mLockscreenPollMask=0
mTechMask: 0
mEnableLPD: true
mEnableReader: false
mEnableHostRouting: false
mEnableP2p: falsemEnable2ndLevelMenu: false
mIsSendEnabled=false
mIsReceiveEnabled=false
mLinkState=LINK_STATE_DOWN
mSendState=SEND_STATE_NOTHING_TO_SEND
mCallbackNdef=android.nfc.IAppCallback$Stub$Proxy@4d6bfbd
mMessageToSend=null
Registered HCE services for current user:
ComponentInfo{com.huawei.wallet/com.huawei.nfc.carrera.
lifecycle.swipeservice.NFCOffHostApduService} (Description: 华为钱包)
Static AID groups:
Category: payment
AID: 325041592E5359532E4444463031
AID: A0000003330101020063020000000301
Dynamic AID groups:
Settings Activity: null
Routing Destination: secure element
Registered HCE-F services for current user:
Preferred services (in order of importance):
*** Current preferred foreground service: null
*** Current preferred payment service: ComponentInfo{com.huawei.wallet/com.huawei.nfc.
carrera.lifecycle.swipeservice.NFCOffHostApduService}
Next tap default: null
Default for foreground app (UID: 0): null
Default in payment settings: ComponentInfo{com.huawei.wallet/com.huawei.nfc.
carrera.lifecycle.swipeservice.NFCOffHostApduService}
Payment settings allows override: true
AID cache entries:
"325041592E5359532E4444463031" (category: payment)
*DEFAULT* ComponentInfo{com.huawei.wallet/com.huawei.nfc.
carrera.lifecycle.swipeservice.NFCOffHostApduService} (Description: 华为钱包)
"A0000003330101020063020000000301" (category: payment)
*DEFAULT* ComponentInfo{com.huawei.wallet/com.huawei.nfc.
carrera.lifecycle.swipeservice.NFCOffHostApduService} (Description: 华为钱包)
Service preferred by foreground app: null
Preferred payment service: ComponentInfo{com.huawei.wallet/com.huawei.nfc.carrera.
lifecycle.swipeservice.NFCOffHostApduService}
Routing table:
Default route: secure element
T3T Identifier cache entries:
HCE-F routing table:
Bound HCE-A/HCE-B services:
Bound HCE-F services:
mOverrideIntent=null
mOverrideFilters=null
mOverrideTechLists=null
libnfc llc error_count=0
使用安全元件进行卡模拟
不涉及安全元件的 NFC 卡模拟
Android 的 HCE 协议栈
具体而言,Android 4.4 支持基于 NFC-Forum ISO-DEP 规范(基于 ISO/IEC 14443-4)的模拟卡,并处理应用协议数据单元 (APDU)(如 ISO/IEC 7816-4 规范中所定义)。Android 要求仅使用 Nfc-A (ISO/IEC 14443-3 Type A) 技术模拟 ISO-DEP。也可以支持 Nfc-B (ISO/IEC 14443-4 Type B) 技术。图 显示了所有这些规范的分层。
HCE 服务
Android 中的 HCE 架构基于 Android Service
组件(称为“HCE 服务”)。服务的一项关键优势是可以在后台运行,而不显示任何界面。这非常适合很多 HCE 应用(例如会员卡或公交卡),用户不需要启动应用即可使用。设备触碰到 NFC 读取器时,系统会启动正确的服务(如果服务尚未运行),并在后台执行交易。当然,如果合适,您也尽可从自己的服务启动额外的界面(例如用户通知)
服务选择
当用户手拿设备触碰 NFC 读取器时,Android 系统需要知道 NFC 读取器实际想与哪项 HCE 服务通信。这时 ISO/IEC 7816-4 规范就派上用场了:它定义了一种以应用 ID (AID) 为核心的应用选择方式。一个 AID 最多可包含 16 个字节。如果您要模拟适用于现有 NFC 读取器基础设施的卡,这些读取器使用的 AID 通常为人熟知且已公开注册(例如,支付网络 Visa 和 MasterCard 等的 AID)。
如果您想为自己的应用部署新的读取器基础设施,则需要注册自己的 AID。AID 的注册流程在 ISO/IEC 7816-5 规范中得到了定义。如果您要部署 Android 版 HCE 应用,Google 建议您根据 7816-5 规范注册一个 AID,以避免与其他应用发生冲突。
同时运行安全元件和主机卡模拟的 Android 设备