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

时间:2016-02-05 16:41:24

标签: javacard apdu

我在javacard applet中有这个方法:

 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命令的正确方法是什么?

3 个答案:

答案 0 :(得分:3)

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

正确的命令是

0x80 0x40 0x00 0x00 0x00

还有一个问题:您的小程序未发送状态字6D00,它由卡管理器小程序发送

AID = A00000006203010801

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

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

答案 1 :(得分:2)

该卡的全球平台类字节为compare。所以你应该发送:

0x80

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

答案 2 :(得分:0)

最后这个命令对我有用。

由于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字段是空的。因此,身体是空的。

  • 在案例2中,长度Lc为空;因此Lc字段和数据字段为空。 Le的长度不为空;因此Le字段存在。因此,身体由Le领域组成。

  • 在案例3中,长度Lc不为空;因此存在Lc字段,数据字段由Lc后续字节组成。长度Le为空;因此Le字段是空的。因此,主体由Lc字段和数据字段组成。

  • 在案例4中,长度Lc不为空;因此存在Lc字段,数据字段由Lc后续字节组成。长度Le也不为空;因此Le字段也存在。因此,正文由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

我在乐场里得到了词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;