邹德强(CaesarZou)的专栏

Google开始放出HCE的支持后,掀起了巨大的反响。 摆脱了SWP-SIM对运营商的依赖,摆脱了eSE对手机厂商的依赖,其对于产业生态的影响不言而喻。网上基于HCE的前景和应用讨论的不亦乐乎,但技术层面的资料却乏善可陈。现我们就通过一个具体的实现来揭秘HCE,同时给出一个技术层面的理解。

首先,需要的环境:

一个支持Android 4.4.2 SDK的开发环境:可以是eclipse插件或者ADT工具。可以到google的网站上去下载:。 (此处攻略漫天飞,搞不定的同学自己搜)

一个支持HCE的测试手机:目前可以确定使用了NXP PN547作为CLF的NFC手机已经打通了HCE。市面上可见的目前有Sony Xperia Z2 和 Samsung Galaxy S5。本次测试使用Xperia Z2。(CLF芯片不包含在手机发布的资料里,最终确定Z2的CLF芯片还是依靠网上流出的拆机图)

一份参考资料:里面写的非常细致,我摘要一下:

1. HCE工作在ISO 7816-4也就是ISO-DEP层面。(想模拟Mifare标签的同学洗洗睡吧)

2.命令的派发是基于系统接管SelectbyName指令,以及HCE服务注册到系统的AID来完成的。HCE的派发高于SE,不支持logic channel,也不支持GP的AID部分匹配。

3.HCE以Android服务的方式启动,通过接口函数响应APDU。可以配置多个AID(AID Group),可以配置类型–支付类或者其它类,该类型用于AID冲突时系统的策略。支付类是通过设置默认应用,而其它类则是UI弹出选择提示。

4.屏幕关闭的状态下HCE不可用,屏幕锁定状态下HCE可以选择支持,也可以选择提示用户解锁再支持。

5.在终端只有HCE没有SE的情况下,ISO 14443-3的非接参数由Android接管,UID使用随机数,请勿使用HCE实现任何基于UID的ID卡。

6.Open Mobile API并不能向访问SE一样访问HCE。

然后,我们开始编码了,首先实现Service:

package com.broadthinking.hcedemo;import android.nfc.cardemulation.HostApduService;import android.os.Bundle;import android.util.Log;public class MyHostApduService extends HostApduService {private int messageCounter = 0;@Overridepublic byte[] processCommandApdu(byte[] apdu, Bundle extras) {if (selectAidApdu(apdu)) {Log.i("HCEDEMO", "Application selected");return getWelcomeMessage();}else {Log.i("HCEDEMO", "Received: " + new String(apdu));return getNextMessage();}}private byte[] getWelcomeMessage() {return "Hello Desktop!".getBytes();}private byte[] getNextMessage() {return ("Message from android: " + messageCounter++).getBytes();}private boolean selectAidApdu(byte[] apdu) {return apdu.length >= 2 && apdu[0] == (byte)0 && apdu[1] == (byte)0xa4;}@Overridepublic void onDeactivated(int reason) {Log.i("HCEDEMO", "Deactivated: " + reason);}}其中:processCommandApdu用以重载传入接收到的CAPDU,函数返回值作为RAPDU。但此接口的调用使用程序主栈,如果处理时间较长(比如基于云的处理),则需要启动处理线程,并返回null,并在处理线程结束后主动调用sendResponseApdu来发送RAPDU。

继续配置Android环境 AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android=""package="com.broadthinking.hcedemo"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="19"android:targetSdkVersion="19" /><uses-permission android:name="android.permission.NFC" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.broadthinking.hcedemo.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><serviceandroid: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-dataandroid:name="android.nfc.cardemulation.host_apdu_service"android:resource="@xml/apduservice" /></service></application></manifest>

几个关键点:

用户授权:android.permission.NFC 服务授权:android.permission.BIND_NFC_SERVICE exported:必须为true initent-filter:android.nfc.cardemulation.action.HOST_APDU_SERVICE meta-data:指定服务的细节,见apduservice.xml

<host-apdu-service xmlns:android=""android:description="servicedesc"android:requireDeviceUnlock="false" ><aid-groupandroid:category="other"android:description="aiddescription" ><aid-filter android:name="F0010203040506" /><aid-filter android:name="F0394148148100" /></aid-group></host-apdu-service> 几个关键点:

也有伤心的,既有令人兴奋的,也有令人灰心的,

邹德强(CaesarZou)的专栏

相关文章:

你感兴趣的文章:

标签云: