使用智能卡IO时无法检索第二张卡的ATR

时间:2015-04-04 20:09:18

标签: java smartcard-reader contactless-smartcard pcsc acr122

在某些背景下,我使用了PN532用户手册中指定的In_List_Passive_Target命令来检索终端字段中所有卡的UID。我还使用伪命令FF 00 00 00 04让ACR122U将这些命令发送到PN532。

>>  FF 00 00 00 04 D4 4A 01 00           # In_List_Passive_Target (1)
<<  D5 4B 01 01 00 04 08 04 3E 58 A7 D1  # Response including UID (1)
>>  FF 00 00 00 04 D4 4A 01 00           # In_List_Passive_Target (2)
<<  D5 4B 01 01 00 04 08 04 9E 69 A7 D1  # Response including UID (2)
>>  FF 00 00 00 04 D4 4A 01 00           # In_List_Passive_Target (3)
<<  D5 4B 00                             # No more cards in field (3)

既然我已经这样做了,我想逐一选择这些。我可以通过暂停卡(In_Deselect)来完成此操作,然后使用In_List_Passive_Target命令并使用它的UID选择下一个卡。

但是,每次选择卡片时,我都想知道它返回的ATR。使用Java智能卡IO API证明这很困难,因为终端创建的卡对象始终是相同的卡(因此返回相同的ATR),即使我断开卡然后再创建一个新卡。考虑到我是否通过PN532终端命令In_Data_Exchange与卡通信,这是很奇怪的,它是正确的不同卡(不是通过Card对象可访问的旧卡)。我需要ATR能够检测到它是哪种类型的卡(Mifare Classic,Desfire,Ultralight等)

以下是我为收集卡片而创建的功能:

public static void getCardsInField()
    {
        cardList = new ArrayList<AbstractCard>();
        Boolean loop = true;

        // Card already connected to the terminal
        byte[] firstCardUID = transmitADPUCommand(GET_ADDRESS);
        MifareClassic firstCard = new MifareClassic(cardChannel, firstCardUID);
        cardList.add(firstCard);

        System.out.println(firstCard);
        System.out.println(readable(card.getATR().getBytes()));

        while(loop)
        {
            byte[] inDeselectResponse = transmitADPUCommand(IN_DESELECT); // Deselect current card
            byte[] inListPassiveTargetsResponse = transmitADPUCommand(IN_LIST_PASSIVE_TARGETS); // Select a new card

            System.out.println(">>  " + readable(IN_LIST_PASSIVE_TARGETS));
            System.out.println("<<  " + readable(inListPassiveTargetsResponse));

            // Trying to create a new card object for new card
            try
            {
                card.disconnect(true);
                card = cardTerminal.connect("*");
                cardChannel = card.getBasicChannel();
            }
            catch (CardException e)
            {
                e.printStackTrace();
            }

            if (Arrays.equals(inListPassiveTargetsResponse, IN_LIST_PASSIVE_TARGET_RESPONSE_NO_TARGETS)) // no more targets
            {
                loop = false;
            }
            else
            {
                byte[] loopCardUID = extractUID(inListPassiveTargetsResponse);
                MifareClassic loopCard = new MifareClassic(cardChannel, loopCardUID);
                cardList.add(loopCard);

                System.out.println(loopCard);
                System.out.println(readable(card.getATR().getBytes())); // this should be different ATR but it is the old cards atr
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

非接触式卡没有ATR(应答复位)。 ATR仅由接触卡(ISO / IEC 7816-3响应于解除复位引脚的响应)生成。此外,PC / SC模拟非接触式卡的ATR(基于卡的某些参数),因为PC / SC主要是为接触卡设计的,因此PC / SC API需要ATR可用。

非接触式卡片具有其他值。例如,基于ISO / IEC 14443类型A的卡具有ATQA(SENS_RES),SAK(SEL_RES),UID(NFCID1),并且可能具有ATS(接近ATR是什么)。基于ISO / IEC 14443 B类的非接触式卡具有相似的值。

您将获得识别卡片类型以响应InListPassiveTarget命令所需的所有信息:

Card 1: D5 4B 01 01 00 04 08 04 3E 58 A7 D1
Card 2: D5 4B 01 01 00 04 08 04 9E 69 A7 D1

对于卡1,此数据解码为:

  • ATQA(SENS_RES)= 00 04
  • SAK(SEL_RES)= 08
  • UID(NFCID1)= 3E 58 A7 D1
  • ATS =无

对于卡2,此数据解码为:

  • ATQA(SENS_RES)= 00 04
  • SAK(SEL_RES)= 08
  • UID(NFCID1)= 9E 69 A7 D1
  • ATS =无

因此,两张卡都有ATQA = 00 04和SAK = 08,这意味着它们很可能是MIFARE Classic 1K或MIFARE Plus。

请参阅MIFARE Type Identification Procedure以获取用于识别恩智浦ISO / IEC 14443 A型卡的全面值列表。