2

我有一张带有小程序(cardlet)的 SIM 卡。如果我可以将 Android 设备中的默认安全元素设置为 UICC,我可以通过非接触式接口向 UICC 发送命令。

我的 NFC 阅读器向 NFC 控制器发送一个带有“SELECT AID A0000001234567890”的 APDU,NFC 控制器将把它发送到 UICC 安全元件上的我的小程序(已处理访问控制)。

现在我想为无法将默认安全元素设置为 UICC 的设备使用此功能。

如果我理解正确,因为原则上我不需要 Android 应用程序,我仍然必须使用一个虚拟的 Android 应用程序并在其清单中声明一个所谓的“脱离主机服务”。

有人可以指导我如何将选择安装在安全元件上的小程序的 AID 的 APDU 和后续 APDU 路由到 UICC 安全元件吗?

这是我的第一次尝试,但也许有人对我有一个工作示例或一些指导/更正。

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

1 回答 1

2

您的开始看起来不错,并且使用 offhost-apdu-service 应该可以在支持路由卡仿真与安全元件通信的设备上正常工作。请注意,某些设备根本不支持此功能。

但是,您的 XML 文件存在一些问题:

  1. 支付类别中的卡片模拟服务必须声明服务横幅可绘制资源。服务横幅应该是尺寸为 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>
    
  2. 服务必须在清单文件的应用程序标签内声明(注意我还更改了服务的名称以避免与框架类的命名冲突):

    <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>
    
  3. 除了在清单中声明服务外,您还需要为服务实际创建 Java 实现。就像是:

    public class MyOffHostApduService extends OffHostApduService {
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
    
  4. <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 ...>
    
  5. <uses-library ...>元素必须是该元素的直接子<application ...>元素。但是,您可能无论如何都不会使用这个库,并且可以完全放弃它。

最后,请注意,您示例中的 AID 无效,因为它没有按完整字节对齐。例如,一个有效的 AID 是A00000012345678900. (虽然我假设这只是在屏蔽您的原始 AID 期间发生的,对吧?)

于 2016-06-24T09:34:52.810 回答