【问题标题】:How to define an APDU for STORE DATA for Host Card Emulation?如何为主机卡仿真的 STORE DATA 定义 APDU?
【发布时间】:2018-12-14 09:53:56
【问题描述】:

我一直在查看全球平台规范,了解如何为我的应用程序定义一个将使用主机卡仿真 (HCE) 的 APDU。我的应用程序应该让一部手机通过 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 手机发送到读卡器手机? 我错过了什么? 需要做什么?

【问题讨论】:

    标签: android nfc uniqueidentifier apdu hce


    【解决方案1】:

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

    【讨论】:

    • 好的,非常感谢。 System.arraycopy(id,0,answer,0,id.length); 的意义是什么?我知道它正在复制 ID 字符串字节数组,但是在哪里?到“答案”数组?但这还没有被初始化,它甚至会去哪里?
    • @hazed2.0 对,这是简化我的答案的剩余部分。它应该是responseApdu 而不是answer。我现在更正了。
    • 另外,是不是应该返回commandApdu,为什么不返回responseApdu?
    • @Hazed2.0 当我写那篇文章时,我显然太累了。现已修复。
    • 另外我如何将 apdu 发送到 responseApdu ?请在这里回复我的帖子stackoverflow.com/questions/51331045/…
    猜你喜欢
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多