如何为主机卡仿真的 STORE DATA 定义 APDU?

How to define an APDU for STORE DATA for Host Card Emulation?

我一直在查看全球平台规范,了解如何为我的将使用主机卡仿真 (HCE) 的应用程序定义 APDU。我的应用程序应该有一个 phone 通过 HCE 表现得像 NFC 标签,另一个 phone 作为 NFC reader。我试图在 phone 之间传输的任意数据只是一个包含 ID 号的简单字符串,但我不确定如何在代码中应用它。我已经查看了不同字节命令的含义,但我真的不确定如何应用它。

我想我需要使用 STORE DATA 命令,但我不确定如何凭直觉去做,也不太明白。我目前正在查看 HCE 方面而不是 reader 方面。

到目前为止,这是我在 HCE 方面的代码

public class SecondaryActivity extends HostApduService {

@Override
public void onDeactivated(int reason) {

}

@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
    String inboundApduDescription;
    byte[] responseApdu;

    if (Arrays.equals(AID_SELECT_APDU, commandApdu)) {
        inboundApduDescription = "Application selected";
        Log.i("HCEDEMO", inboundApduDescription);
        byte[] answer = new byte[2];
        answer[0] = (byte) 0x90;
        answer[1] = (byte) 0x00;
        responseApdu = answer;
        return responseApdu;

    }
    return commandApdu;
}

private static final byte[] AID_SELECT_APDU = {
        (byte) 0x00,
        (byte) 0xA4,
        (byte) 0x04,
        (byte) 0x00,
        (byte) 0x07,
        (byte) 0xF0, (byte) 0x39, (byte) 0x41, (byte) 0x48, (byte) 0x14, (byte) 0x81, (byte) 0x00,
        (byte) 0x00
};

private static final byte[] STORE_DATA = {
        (byte) 0x00,
        (byte) 0xA4,
        (byte) 0x04,
        (byte) 0xA5, // forproprietary data according to the spec
        (byte) 0xE2,
        (byte) 0x66, (byte) 0x39, (byte) 0x41, (byte) 0x48, (byte) 0x14, (byte) 0x81, (byte) 0x00,
        (byte) 0x00
};

private static final byte[] INSTALL = {
        (byte) 0x00,
        (byte) 0x00,
};

}

如何将数据从 HCE phone 发送到 reader phone? 我错过了什么? 需要做什么?

您几乎可以为 HCE 定义任何 APDU 命令。仅需要初始 SELECT(通过 AID)命令。之后,只要遵守ISO/IEC7816对于command/responseAPDU结构的规则,就可以创建自己的命令集(或者尝试遵循ISO/IEC7816-4命令),并坚持到有效的 CLA、INS 和状态字值。

由于您只想传输一个 ID,因此您可以直接发送此 ID 以响应 SELECT 命令:

private static final String ID = "1234567890"

@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
    byte[] responseApdu = new byte[] { (byte)0x6F, (byte)0x00 };

    if ((commandApdu != null) && (commandApdu.length >= 4)) {
        if ((commandApdu[0] == (byte)0x00) && (commandApdu[1] == (byte)0xA4) && (commandApdu[2] == (byte)0x04) && (commandApdu[3] == (byte)0x00)) {
            Log.i("HCEDEMO", "Application selected");

            byte[] id = ID.getBytes(Charset.forName("UTF-8"));
            responseApdu = new byte[id.length + 2];
            System.arraycopy(id, 0, responseApdu, 0, id.length);
            responseApdu[id.length] = (byte)0x90;
            responseApdu[id.length + 1] = (byte)0x00;
        }
    }
    return responseApdu;
}