【问题标题】:How to send a command APDU to a HCE device?如何向 HCE 设备发送命令 APDU?
【发布时间】:2018-07-13 18:34:01
【问题描述】:

我的应用程序的 AID 是 F239856324897348,我已经为它构建了一个 SelectAID APDU。现在我如何将它实际发送到正在使用主机卡仿真的接收 Android 设备。

我已经创建了一个 HCE 服务来响应一个响应 APDU,就像在这个线程中一样:How to define an APDU for STORE DATA for Host Card Emulation?

public static byte[] SelectAID = new byte[]{
        (byte) 0xF2, (byte) 0x39, (byte) 0x85, (byte) 0x63,
        (byte) 0x24, (byte) 0x89, (byte) 0x73, (byte) 0x48};

private void commandAPDU(byte[] apdu){
   //where do I go from here...
}

commandAPDU(SelectAID);

【问题讨论】:

    标签: android nfc apdu contactless-smartcard hce


    【解决方案1】:

    APDU 的格式在 ISO/IEC 7816-4 中定义。典型的 SELECT(通过 AID)命令如下所示:

    +-----+-----+-----+-----+-----+------ ------+-----+ |共轭亚油酸 | INS | P1 | P2 | LC |数据 |乐 | +-----+-----+-----+-----+-----+------ ------+-----+ | 00 | A4 | 04 | 00 | XX |援助 | 00 | +-----+-----+-----+-----+-----+------ ------+-----+

    你可以这样创建它:

    private byte[] selectApdu(byte[] aid) {
        byte[] commandApdu = new byte[6 + aid.length];
        commandApdu[0] = (byte)0x00;  // CLA
        commandApdu[1] = (byte)0xA4;  // INS
        commandApdu[2] = (byte)0x04;  // P1
        commandApdu[3] = (byte)0x00;  // P2
        commandApdu[4] = (byte)(aid.length & 0x0FF);       // Lc
        System.arraycopy(aid, 0, commandApdu, 5, aid.length);
        commandApdu[commandApdu.length - 1] = (byte)0x00;  // Le
        return commandApdu;
    }
    

    然后您可以将此类 APDU 命令发送到通过阅读器模式 API 发现的标签/HCE 设备:

    public abstract void onTagDiscovered(Tag tag) {
        IsoDep isoDep = IsoDep.get(tag);
        if (isoDep != null) {
            try {
                isoDep.connect();
                byte[] result = isoDep.transceive(selectApdu(SelectAID));
            } except (IOException ex) {
            } finally {
                try {
                    isoDep.close();
                } except (Exception ignored) {}
            }
        }
    }
    

    【讨论】:

    • 好的,那么 00 A4 04 00 XX 在 commandApdu 数组中表示在哪里?为什么不是 commandApdu[0] = (byte)0x00;命令Apdu[1]=(字节)0xA4; commandApdu[2] = (byte)0x04 等 ?我只是将 AID 字符串写为 Aid.toBytes() 并通过 selectApdu() 传递它吗?它是如何选择正确的 AID 的?
    • @Hazed2.0 你又惹到我了。固定。
    • @Hazed2.0 AID 作为字节数组传递(您已经在代码中将其定义为SelectAID)。你不能使用"F239856324897348".toBytes(),因为这会给你字符串的UTF-8编码字节,而不是十六进制文字的字节表示。
    • 好的,谢谢现在更有意义了。还有 commandApdu[4] = (byte)(aid.length & 0x0FF);这里的aid.length有什么意义?我们是否表示字节数组的结束?它是 0xFF 还是 0x0FF ?
    • @Hazed2.0 commandApdu[4] 包含 Lc 字段,即命令 DATA 字段(由 AID 组成)的长度。 0xFF 和 0x0FF 之间没有区别,因为默认情况下 Java 数字文字是整数。我只是更喜欢前导零来明确它掩盖了一个字节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多