3

我目前正在为我的 Galaxy s4 实现 HCE。我有一个支持 7816-4 的 Omnikey 5321-cl 阅读器。我的 android 类如下所示:

public class NfcHceService extends HostApduService{
private int counter         = 0;

@Override
public void onStart(android.content.Intent intent, int startId)
{
    new Thread(new Runnable() {

        @Override
        public void run()
        {
            while (true)
            {
                Log.d("HCE", String.valueOf(counter));
                counter++;
                try
                {
                    Thread.sleep(1000);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }).run();
}

@Override
public byte[] processCommandApdu(byte[] apdu, Bundle extras)
{
    byte[] response = null;
    if (apdu[2] == 0xA4)
    {
        // return selecting applet
        response = new byte[] { (byte) 0x90, 0x00 };

    }
    return response;
}

@Override
public void onDeactivated(int reason)
{
    android.os.Debug.waitForDebugger();
    Log.d("HCE", "onDeactivated");

}

}

我的读者类看起来像这样:

private static final byte[] CLA_INS_P1_P2   = { 0x00, (byte) 0xA4, 0x04, 0x00 };
private static final byte[] AID_ANDROID     = { (byte) 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };

private static byte[] createSelectAidApdu(byte[] aid)
{
    byte[] result = new byte[6 + aid.length];
    System.arraycopy(CLA_INS_P1_P2, 0, result, 0, CLA_INS_P1_P2.length);
    result[4] = (byte) (aid.length);
    System.arraycopy(aid, 0, result, 5, aid.length);
    result[result.length - 1] = 10;
    return result;
}

public static void Create_MF() throws CardException
{

    // --Variable declaration
    Card card = null;
    ResponseAPDU answer = null;
    // ---------------------------------------------

    // --1--Establish connection with the smart card
    TerminalFactory factory = TerminalFactory.getDefault();
    List<CardTerminal> terminals = factory.terminals().list();
    // Use the first terminal
    CardTerminal terminal = terminals.get(1);
    // Connect with the card
    card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    // ---------------------------------------------

    byte[] selectAidApdu = createSelectAidApdu(AID_ANDROID);

    answer = channel.transmit(new CommandAPDU(selectAidApdu));

我对 hce 服务的 AID 是 F0010203040506。

我现在的问题是我在我的 android 设备上得到了一个正确的 Select APDU,如下所示:

> RX: Type 4 Tag Command (13 bytes)
  CLA:0x00
  INS:0xA4(Select)
  P1:0x04(Name)
  P2:0x00(First or Only)
  LC:0x07(7)
  Data(7 bytes)
   00: f0 01 02 03 04 05 06
  Le:0x0A(10)

但我得到一个响应代码 6A82。据我了解,这意味着该设备找不到该服务。但我不明白为什么。有人可以帮忙吗?

显现:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.hce"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
    android:minSdkVersion="19"
    android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" />
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <service
        android:name=".NfcHceService"
        android:exported="false"
        android:permission="android.permission.BIND_NFC_SERVICE" >
        <intent-filter>
            <action android:name="android.nfc.cardemulation.HOST_APDU_SERVICE" />
        </intent-filter>
        <meta-data
            android:name="android.nfc.cardemulation.host_apdu_service"
            android:resource="@xml/hce_service" />
    </service>
</application>

和 xml 文件:

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/my_app_hce_service" >
<aid-group
    android:category="other"
    android:description="@string/my_app_aid_group" >
    <aid-filter android:name="F0010203040506" />
</aid-group></host-apdu-service>

更新

public static void Create_MF() throws CardException
{

    // --Variable declaration
    Card card = null;
    ResponseAPDU answer = null;
    // ---------------------------------------------

    // --1--Establish connection with the smart card
    TerminalFactory factory = TerminalFactory.getDefault();
    List<CardTerminal> terminals = factory.terminals().list();
    // Use the first terminal
    CardTerminal terminal = terminals.get(1);
    // Connect with the card
    card = terminal.connect("*");
    CardChannel channel = card.getBasicChannel();
    // ---------------------------------------------

    byte[] selectAidApdu = { 0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; // createSelectAidApdu(AID_ANDROID);

    answer = channel.transmit(new CommandAPDU(selectAidApdu));}

更新 2

我试图实现 isDefaultServiceForAid()。但我不确定我是否正确使用它以及它是否符合我的要求。

    CardEmulation card = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this));
    ComponentName comp = new ComponentName(getApplicationContext(), NfcHceService.class);
    boolean tmp = card.isDefaultServiceForAid(comp, "F0010203040506");

它真的测试了我的服务的 AID 还是其他什么?我想测试我的服务是否可以使用我在我的清单中声明的​​ hce_service.xml 中指定的 AID 访问。

4

4 回答 4

1

错误的6A82意思是file not found

在这种情况下,这意味着您选择的 AID 不存在。

这可能是由于您选择f0 01 02 03 04 05 06的 AID 与您的 AndroidManifest.xml 中指定的AID 不匹配所致

ISO 7816 参考这里

更新:

通过检查您更新的代码,您似乎在 APDU 的末尾添加了另一个字节,即0x10. 尝试从函数中删除以下行createSelectAidApdu()

result[result.length - 1] = 10;

另外,我不确定你为什么将最后一个字节设置为 10,它等于十进制的 16。请注意,最后一个字节通常用于指定目标设备预期/请求的数据量。它并不总是必需的,选择应用程序命令就是这种情况。

于 2014-07-07T09:53:53.500 回答
0

我认为 AID 选择没问题。如果 Android 没有用于 AID 的应用程序,它什么也不做,甚至不接收错误代码。

我怀疑问题是应用程序返回 null 作为消息,因此 Android 可能会发回错误代码。

以下 if 语句测试是否定的,因为 apdu[2] 实际上是(字节)0x04。apdu[1] 将是(字节)0xA4。

byte[] response = null;
if (apdu[2] == 0xA4)
{
    // return selecting applet
    response = new byte[] { (byte) 0x90, 0x00 };

}
return response;
于 2014-11-05T23:25:37.410 回答
0

我一直在玩类似的东西。

我注意到您的意图过滤器指定了“android.nfc.cardemulation.HOST_APDU_SERVICE”的操作,但正确的操作似乎是“android.nfc.cardemulation.action.HOST_APDU_SERVICE” - 请参阅http://developer.android.com/指南/主题/连接性/nfc/hce.html了解详细信息。

在意图过滤器中使用此操作,我成功地为我的 AID 调用了我的 Android 服务。

祝你好运!

于 2016-03-10T01:06:09.880 回答
0

我只是遇到了类似的问题——我的 AID 两端都是正确的,但仍然找不到服务。

官方 HCE 页面有以下代码段:

<service android: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-data android:name="android.nfc.cardemulation.host_apdu_service"
           android:resource="@xml/apduservice"/>

我注意到<intent-filter>没有<category>标签。我添加了这个,突然可以找到我的服务!见下文:

<intent-filter>
    <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
    <!-- category required!!! this was not included in official android HCE documentation -->
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
于 2016-11-11T17:17:56.397 回答