如何发送 APDU 命令以获得成功响应?

How to send the APDU command to get a success response?

我的 javacard 小程序中有这个方法:

 public void process(APDU apdu)  
{
  byte[] buf = apdu.getBuffer() ;  
  switch(buf[ISO7816.OFFSET_INS])  
   { 
   case 0x40: 
              Util.arrayCopy(hello,(byte)0,buf,ISO7816.OFFSET_CDATA,(byte)5); 
              apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,(byte)5); 
              break; 

   default:  ISOException.throwIt(ISO7816.SW_WRONG_INS) ;  
   }
}

你好:

 private final static byte[] hello =  {0x48, 0x65, 0x6c, 0x6c, 0x6f }; 

我在脚本中发送命令如下:

 powerup;

// Select the installer applet
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;

// create TestApplet applet
0x80 0xB8 0x00 0x00 0xd 0xb 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00 0x00 0x00 0x7F;

//show hello message
0x40 0x00 0x00 0x00;  //this is the command mentioned in tutorial which gave error

powerdown;

前两条命令成功,但最后一条出现错误,因为命令格式不正确。

我也试过这个命令:

     0x00 0x40 0x00 0x00 0x00 0x7f; 

但它给了我 6d00 的响应,这意味着 INS 不支持 vlaue。

这是实际的回复:

CLA: 80, INS:40, P1:00,P2:00,Lc:00,Le:00,SW1:6d,SW2:00

预期的响应是获得 hello 值以及成功响应 9000

我正在关注tutorial

发出 APDU 命令的正确方法是什么?

卡的全球平台 class 字节为 0x80。所以你应该发送:

 0x80 0x40 0x00 0x00 0x00

您发送的第一个 APDU 0x40 0x00 0x00 0x00 是错误的,因为 0x40 被视为 class 字节而 0x00 被视为指令。

如@BzH 的回答中所述,命令 0x40 0x00 0x00 0x00 不正确。

正确的命令是

0x80 0x40 0x00 0x00 0x00.

还有一个问题:状态字6D00不是你的小程序发送的,是卡管家小程序发送的

AID = A00000006203010801

您在 powerup 之后 select 编辑了。卡片管理器小程序不知道 INS = 0x40 指令,因此不知道状态代码。在发送任何命令之前,您必须 select 您的小程序:

00 A4 04 00 [Lc] [... AID of your applet instance...]
80 40 00 00 00

这个命令终于对我有用了。

由于 APDU 命令应该以一种格式给出,

向APDU发送命令有四种情况:

Case    Command data    Expected response data
1        No data            No data
2        No data            Data
3        Data              No data
4        Data               Data
  • 情况1,长度Lc为空;因此 Lc 字段和数据字段为空。长度 Le 也为空;因此 Le 字段为空。因此,body 为空。

  • 情况2,长度Lc为空;因此 Lc 字段和数据字段为空。 Le 的长度不为空;因此存在 Le 场。因此,body 由 Le 字段组成。

  • 情况3,长度Lc不为空;因此 Lc 字段存在,数据字段由 Lc 后续字节组成。长度 Le 为空;因此 Le 字段为空。因此,body 由 Lc 字段和数据字段组成。

  • 情况4,长度Lc不为空;因此 Lc 字段存在,数据字段由 Lc 后续字节组成。长度 Le 也不为空;因此 Le 场也存在。因此,body 由 Lc 字段、数据字段和 Le 字段组成。

所以在我的情况下是情况 4,我需要发送一些字节,并获取一些字节。

所以这种情况下的命令应该是:

  0x00 0x40 0x00 0x00 0x05 0x00 0x40 0x00 0x00 0x00 0x05;
   CLA INS    P1   P2  Lc   b1   b2   b3   b4   b5   Le

      Lc- input byte length (0x05 followed by 5 bytes of input: 0x00 0x40 0x00 0x00 0x00)
      Le- expeted output byte length (H,e,l,l,o in my case it is 5 bytes. Hence 0x05)

我得到的回复是:

 CLA:00 INS:40 P1:00 P2:00 Lc:05,00,40,00,00,00 Le:05,48,65,6c,6c,6f SW1:90 SW2:00

我在 Le 字段中得到了单词 H,e,l,l,o。

正如@Vojta 所建议的,我犯的另一个错误是,我 运行 命令没有选择小程序,

所以,正确的顺序应该是

 power up

 //create installer applet

 //create testapplet

 //select test appplet   (I missed this step in my question)

 //run get Hello Command

 powerdown;