在测试发送APDU时无法选择AID卡管理器

时间:2014-12-22 10:15:26

标签: java applet javacard apdu pcsc

我正在尝试将applet加载到智能卡中,之后我想用以下代码进行一些测试:

import javax.smartcardio.*;
import java.util.*;

public class TestSmartCardIO {

    public static String toString(byte[] bytes) {
        StringBuffer sbTmp = new StringBuffer();
        for(byte b : bytes){
            sbTmp.append(String.format("%X", b));
        }
        return sbTmp.toString();
    }

    public static void main(String[] args) {
        try {
            TerminalFactory factory = TerminalFactory.getDefault();
            List terminals = factory.terminals().list();
            System.out.println("Terminals count: " + terminals.size());
            System.out.println("Terminals: " + terminals);

            // Get the first terminal in the list
            CardTerminal terminal = (CardTerminal) terminals.get(0);

            // Establish a connection with the card using
            // "T=0", "T=1", "T=CL" or "*"
            Card card = terminal.connect("*");
            System.out.println("Card: " + card);

            // Get ATR
            byte[] baATR = card.getATR().getBytes();
            System.out.println("ATR: " + TestSmartCardIO.toString(baATR) );

            CardChannel channel = card.getBasicChannel();

            /*SELECT Command
             See GlobalPlatform Card Specification (e.g. 2.2, section 11.9)
             CLA: 00
             INS: A4
             P1: 04 i.e. b3 is set to 1, means select by name
             P2: 00 i.e. first or only occurence
             Lc: 08 i.e. length of AID see below
             Data: A0 00 00 00 03 00 00 00
             AID of the card manager,
             in the future should change to A0 00 00 01 51 00 00*/

             byte[] baCommandAPDU = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x08, (byte) 0xA0, (byte) 0x00, 
                                    (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00};
            System.out.println("APDU >>>: " + TestSmartCardIO.toString(baCommandAPDU));

            ResponseAPDU r = channel.transmit(new CommandAPDU(baCommandAPDU));
            System.out.println("APDU <<<: " + TestSmartCardIO.toString(r.getBytes()));

            // Disconnect
            // true: reset the card after disconnecting card.

            card.disconnect(true);
        } catch(Exception ex)  {
            ex.printStackTrace();
        }
    }
} 

所以我只想测试卡是否被识别,以及我是否可以正确发送APDU。我试图通过APDU选择AID卡管理器,但我得到:

Terminals count: 1
Terminals: [PC/SC terminal OT MicroSD smartcard Reader 1]
Card: PC/SC card in OT MicroSD smartcard Reader 1, protocol T=1, state OK
ATR: 3BDB96081B1FE451F83031C0641A181019005D
APDU >>>: 0A4408A00003000
APDU <<<: 6A82

并且SW1 = 6ASW2 = 82表示该卡未找到AID卡管理员...这是正常的吗? 我真的不明白,我想知道它是否与卡使用协议T = 1有关?非常感谢你的帮助

2 个答案:

答案 0 :(得分:3)

以前全球平台从VISA借用RID(AID的前5个字节)。这是因为历史原因。全球平台现在是一个独立的实体,但开放平台 - 曾经被称为 - 由(至少)VISA启动。有many RID's registered

但据我所知,VISA不想再使用Global Platform来使用他们的RID了。因此请求了一个新的RID。全球平台现在使用了他们自己的A000000003 RID,而不是相当低的A000000151 RID。另一个区别是最后一个字节(可以是任何东西,最多15 - 5 = 10个字节,由组织指定)现在由两个字节而不是三个字节组成。一些操作系统版本实际上出错了,仍然使用三个00字节。

因此,您之前已经有A000000003 000000用于开放平台和早期的GP实施,而对于以后的卡或全球平台规范,您有A000000151 0000来选择卡管理器。从ISO / IEC 7816-4开始,SELECT的处理并不完全清楚。通常,如果您在SELECT中通过NAME提供较小的AID(至少5个字节),则将选择匹配的应用程序。

答案 1 :(得分:1)

只是一个友好的提醒,在野外&#34;使用globalplatform / javacards&#34;可能是一项艰巨的任务,做正确的事情取决于许多因素。您可能希望查看GlobalPlatformPro(以前称为GPJ)。

它应该隐藏许多恼人的技术细节(比如试图找出ISD AID),同时还提供源代码来详细研究,如果你愿意的话。