如何为主机卡仿真的存储数据定义APDU?

时间:2018-07-05 20:28:15

标签: android nfc uniqueidentifier apdu hce

我一直在寻找有关如何为我的应用定义APDU的全球平台规范,它将使用主机卡仿真(HCE)。我的应用程序应该具有一部通过HCE表现为NFC标签的电话,另一部电话充当NFC阅读器。我试图在电话之间传输的任意数据只是一个包含ID号的简单字符串,但是我不确定如何在代码中应用它。我已经看过不同字节命令的含义,但是我真的不确定如何应用它。

我认为我需要使用STORE DATA命令,但是我不确定如何直观地做到这一点,并且不太了解。我目前正在关注HCE方面,而不是读者方面。

到目前为止,这是我在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手机发送到阅读器手机? 我想念什么? 需要做什么?

1 个答案:

答案 0 :(得分:1)

您几乎可以为HCE定义任何APDU命令。仅需要初始的SELECT(通过AID)命令。之后,只要遵守命令/响应APDU结构的ISO / IEC 7816规则,并遵循有效的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;
}