联系人和非接触式接口之间的APDU命令之间的区别

时间:2016-06-29 13:45:18

标签: smartcard javacard contactless-smartcard

我对联系和非接触式接口中的APDU格式有疑问。我有一个ACR122U非接触式读卡器,我研究了它的API(v2.1)。根据该文件,非接触模式下的apdu格式与接触模式不同。例如,联系模式下的SelectApplet命令是:

Command >> 00 A4 04 00 09 [A0,00,00,03,08,00,00,10,00] 00
Response <<61 19

Command APDU >> 00 C0 00 00 19
Response APDU <<61 17 4F 06 00 00 10 00 01 00 79 0D 4F 0B A0 00 00 03 08 00 00 10 00 01 03 90 00

但是在非接触式模式下是:

Command APDU >> FF 00 00 00 12 d4 40 01 00 a4 04 00 09 a0 00 00 03 08 00 00 10 00 1a
Response APDU << 61 20   

Command APDU >> FF C0 00 00 20
Response APDU << d5 41 00 61 17 4f 06 00 00 10 00 01 00 79 0d 4f 0b a0 00 00 03 08 00 00 10 00 01 03 90 00 90 00

但是当我在网上搜索时,他们提到APDU格式之间没有区别。我错了,还有另一种解决办法将APDU发送到非接触式接口吗?

非常感谢。

2 个答案:

答案 0 :(得分:3)

FF基本上是一个转义符,通常用于向读卡器发送特定命令。该读取器读取专用头,其后面是普通APDU。 APDU本身确实只是5字节头之后(以及3字节响应头之后)的部分。对于较短(特定)的APDU,他们似乎执行了一些解决方法。

如果同一个阅读器(在驱动程序级别)处理接触式和非接触式协议,这可能是一个不错的选择。

答案 1 :(得分:2)

你正在混合概念。我会试着让它变得有点清楚。

声明:我不确定以下某些行!

A)卡片类型

有两种双界面卡:

  1. 双接口双芯片。
  2. Dual Interface Single Chipe。
  3. enter image description here 如上所述,关于卡的类型,您可能会收到通过不同接口发送到卡的特定命令的相同或不同的响应。

    可用的卡通常是双接口单芯片。值得注意的是,双芯片双接口可以配置为对不同接口上的相等命令具有相同的响应。

    B)APDU处理程序实体

    在Java Cards中,接收APDU命令的applet可以根据接收命令的接口决定对特定传入命令作出相同或不同的响应。

    例如,下面代码片段中显示的applet,在APDU Command = 00 10 00 00 00的响应中,在接口接触时返回“Contact”,并在接口非接触时返回Contactless

    package testPack;
    
    import javacard.framework.*;
    
    public class TestApp extends Applet
    {
        private static final byte[] data = { (byte)'C', (byte)'o', (byte)'n', (byte)'t', (byte)'a', (byte)'c', (byte)'t',
                                        (byte)'l', (byte)'e', (byte)'s', (byte)'s'};
    
        public static void install(byte[] bArray, short bOffset, byte bLength) 
        {
            new TestApp().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        }
    
        public void process(APDU apdu)
        {
            if (selectingApplet())
            {
                return;
            }
    
            byte transportMedia = (byte) (APDU.getProtocol() & APDU.PROTOCOL_MEDIA_MASK); 
            boolean isContactless = (transportMedia == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_A) || 
             (transportMedia == APDU.PROTOCOL_MEDIA_CONTACTLESS_TYPE_B);
    
            byte[] buf = apdu.getBuffer();
            switch (buf[ISO7816.OFFSET_INS])
            {
            case (byte)0x10:
                apdu.setOutgoing();
                if (isContactless){
                    apdu.setOutgoingLength((short)0x0B);
                    apdu.sendBytesLong(data, (short)0, (short)0x0B);
                }else{
                    apdu.setOutgoingLength((short)0x07);
                    apdu.sendBytesLong(data, (short)0, (short)0x07);
                }
                break;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        }
    
    }
    

    如下工作:

    Connect successful. # via the "Contact" Interface
    Send: 00 A4 04 00 06 01 02 03 04 05 00 00
    Recv: 90 00
    Send: 00 10 00 00 00
    Recv: 43 6F 6E 74 61 63 74 90 00
    Disconnect successful.
    
    Connect successful. # via the "Contactless" Interface
    Send: 00 A4 04 00 06 01 02 03 04 05 00 00
    Recv: 90 00
    Send: 00 10 00 00 00
    Recv: 43 6F 6E 74 61 63 74 6C 65 73 73 90 00
    

    请注意,安全域和卡管理器(负责回答SELECT APDU命令的实体)通常对两个接口都有相同的响应。

    C)APDU命令与伪APDU

    读卡器可能支持读卡器功能管理/控制命令。例如,您可以更改LED的颜色或延迟发出哔声。应该发送到阅读器本身而不是卡的这些命令被命名为Pseudo-APDU命令,通常以0xFF开头(我认为阅读器制造商选择此值因为它已在ISO7816中定义 - 3表示T = 0中的PPSS,T = 1表示NAD,正常applet命令表示为INVALID。

    基于它的USB智能卡读卡器的规格是PCSC。您可以从here免费下载。定义了一些Pseudo-APDU命令,通常读者制造商在他们的产品中实现它们。他们还可以向读者添加一些专有的伪APDU命令,以增加使用存储卡(例如SLE4432 / 42)或使用Mifare卡的功能。

    读者有一个名为 Direct Transmint 命令的Pseudo-APDU命令,它用于向卡发送有效负载。对于您的读者,正如您在问题中提到的,直接传输命令如下:

    enter image description here

    我很快就会在这里添加一些内容! ...