Android NFC:如何将某个 AID 的 APDU 路由到安全元件 UICC(脱离主机路由)
Android NFC: How to route APDUs for one certain AID to secure element UICC (Off-Host-Routing)
我有一张带有小程序(cardlet)的SIM卡。如果我可以将 Android 设备中的默认安全元素设置为 UICC,我就可以通过非接触式接口向 UICC 发送命令。
我的 NFC reader 将带有 "SELECT AID A0000001234567890" 的 APDU 发送到 NFC 控制器,NFC 控制器应将其发送到我在 UICC 安全元素上的小程序(已处理访问控制)。
现在我想让它适用于无法将默认安全元素设置为 UICC 的设备。
如果我理解正确,因为原则上我不需要 Android 申请,我仍然必须使用虚拟 Android 申请并声明一个所谓的 "off-host service" 在其清单中。
有人可以指导我如何将 select 安装在安全元素上的小程序的 AID 和后续 APDU 路由到 UICC 安全元素的 APDU 吗?
这是我的第一次尝试,但也许有人有适合我或某些人的工作示例 guidance/corrections。
AndroidManifest.xml:
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<service android:name=".OffHostApduService" 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"/>
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
</service>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Echo">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<uses-library
android:name="com.android.nfc_extras"
android:required="true" />
</activity>
</application>
apduservices.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="payment">
<aid-filter android:name="A0000001234567890"/>
</aid-group>
</offhost-apdu-service>
您的开始看起来不错,使用 offhost-apdu-service 应该可以在支持路由卡模拟通信到安全元件的设备上正常工作。请注意,有些设备根本不支持此功能。
不过您的 XML 文件存在一些问题:
付款类别中的卡模拟服务 必须 声明服务横幅可绘制资源。服务横幅应为尺寸为 260 x 96 像素的图形文件(例如 .png 文件)。
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/servicedesc"
android:apduServiceBanner="@drawable/servicebanner">
<aid-group android:category="payment"
android:description="@string/servicedesc" >
<aid-filter ... />
</aid-group>
</offhost-apdu-service>
服务必须在清单文件的应用程序标签内声明(请注意,我还更改了服务的名称以避免与框架的命名冲突class):
<application ...>
<activity ...>
...
</activity>
<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>
</application>
除了在清单中声明服务外,您还需要实际创建服务的 Java 实现。类似于:
public class MyOffHostApduService extends OffHostApduService {
public IBinder onBind(Intent intent) {
return null;
}
}
<uses-feature ...>
和 <uses-permission ...>
元素必须是 <manifest>
元素的直接子元素(即与 <application ...>
元素处于同一级别。它们不得在其他标签内使用(如您的服务标签):
<manifest ...>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<application ...>
<uses-library ...>
元素必须是 <application ...>
元素的直接子元素。但是,您可能无论如何都不会使用这个库,并且可以完全放弃它。
最后,请注意您示例中的 AID 无效,因为它未按完整字节对齐。例如,有效的 AID 应该是 A00000012345678900
。 (虽然我假设这只是在为示例屏蔽您的原始 AID 期间发生的,对吧?)
我有一张带有小程序(cardlet)的SIM卡。如果我可以将 Android 设备中的默认安全元素设置为 UICC,我就可以通过非接触式接口向 UICC 发送命令。
我的 NFC reader 将带有 "SELECT AID A0000001234567890" 的 APDU 发送到 NFC 控制器,NFC 控制器应将其发送到我在 UICC 安全元素上的小程序(已处理访问控制)。
现在我想让它适用于无法将默认安全元素设置为 UICC 的设备。
如果我理解正确,因为原则上我不需要 Android 申请,我仍然必须使用虚拟 Android 申请并声明一个所谓的 "off-host service" 在其清单中。
有人可以指导我如何将 select 安装在安全元素上的小程序的 AID 和后续 APDU 路由到 UICC 安全元素的 APDU 吗?
这是我的第一次尝试,但也许有人有适合我或某些人的工作示例 guidance/corrections。
AndroidManifest.xml:
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<service android:name=".OffHostApduService" 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"/>
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
</service>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Echo">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<uses-library
android:name="com.android.nfc_extras"
android:required="true" />
</activity>
</application>
apduservices.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="payment">
<aid-filter android:name="A0000001234567890"/>
</aid-group>
</offhost-apdu-service>
您的开始看起来不错,使用 offhost-apdu-service 应该可以在支持路由卡模拟通信到安全元件的设备上正常工作。请注意,有些设备根本不支持此功能。
不过您的 XML 文件存在一些问题:
付款类别中的卡模拟服务 必须 声明服务横幅可绘制资源。服务横幅应为尺寸为 260 x 96 像素的图形文件(例如 .png 文件)。
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:apduServiceBanner="@drawable/servicebanner"> <aid-group android:category="payment" android:description="@string/servicedesc" > <aid-filter ... /> </aid-group> </offhost-apdu-service>
服务必须在清单文件的应用程序标签内声明(请注意,我还更改了服务的名称以避免与框架的命名冲突class):
<application ...> <activity ...> ... </activity> <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> </application>
除了在清单中声明服务外,您还需要实际创建服务的 Java 实现。类似于:
public class MyOffHostApduService extends OffHostApduService { public IBinder onBind(Intent intent) { return null; } }
<uses-feature ...>
和<uses-permission ...>
元素必须是<manifest>
元素的直接子元素(即与<application ...>
元素处于同一级别。它们不得在其他标签内使用(如您的服务标签):<manifest ...> <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <uses-feature android:name="android.hardware.nfc.hce" android:required="true" /> <application ...>
<uses-library ...>
元素必须是<application ...>
元素的直接子元素。但是,您可能无论如何都不会使用这个库,并且可以完全放弃它。
最后,请注意您示例中的 AID 无效,因为它未按完整字节对齐。例如,有效的 AID 应该是 A00000012345678900
。 (虽然我假设这只是在为示例屏蔽您的原始 AID 期间发生的,对吧?)