如何将 2 步卡响应更改为 1 步?

How to change 2-step card response into 1-step?

我正在 Java Card 中开发一个程序。 有时当我向卡发送命令时,它响应为“0X61 0Xxx”,这意味着存在长度为 0Xxx 的响应,我应该回答以获取它。

我的问题是,我怎样才能避免这种反应并立即得到答案?

提前致谢

视情况而定!

有时您会收到 61XX 因为您正在与这样编写的小程序进行通信!我的意思是小程序的编写方式是 return 使用 GET RESPONSE APDU 命令存储其数据。所以在这种情况下,除了请求小程序开发人员根据需要修改小程序之外,您无能为力。

但有时return上面描述的数据不是小程序,而是智能卡。实际上 T=0 智能卡 return 的数据本身就是这样。所以你只需要将你的智能卡换成支持T=1通讯协议的新卡即可。在这种情况下,您有一个小程序 CAP 文件,当您将它安装到 T=0 卡上时,分两步将其 returns 数据安装到 T=1 智能卡上时,它returns 数据在 1 步。


假设您编写了如下程序。它有四个不同的 APDU 命令 (INS = 00, 01, 02, 03) 到 return temp 字节数组内容给用户:

package soq;

import javacard.framework.*;

public class SOQ extends Applet
{
    byte[] temp = {(byte)'T',(byte)'h',(byte)'i',(byte)'s',
                   (byte)'-',(byte)'I',(byte)'s',(byte)'-',
                   (byte)'A',(byte)'-',(byte)'T',(byte)'e',(byte)'s',(byte)'t'};

    public static void install(byte[] bArray, short bOffset, byte bLength) 
    {
        new SOQ().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
    }

    public void process(APDU apdu)
    {
        if (selectingApplet())
        {
            return;
        }

        byte[] buf = apdu.getBuffer();
        short le;

        switch (buf[ISO7816.OFFSET_INS])
        {
        case (byte)0x00:
            apdu.setOutgoing();
            apdu.setOutgoingLength((short)14);
            apdu.sendBytesLong(temp, (short)0, (short)14);
            break;

        case (byte) 0x01:
            Util.arrayCopyNonAtomic(temp, (short)0, buf, (short)0, (short)14);
            apdu.setOutgoingAndSend((short)0, (short)14);
            break;

        case (byte) 0x02:
            le = apdu.setOutgoing();
            if (le != (short)0x000E){
                ISOException.throwIt((short)0x6C0E);
            }else{
                Util.arrayCopyNonAtomic(temp, (short)0, buf, (short)0, (short)14);
                apdu.setOutgoingLength((short)le);
                apdu.sendBytes((short)0, le);
            }
            break;

        case (byte) 0x03:
            le = apdu.setOutgoing();
            if (le != (short)0x000E){
                ISOException.throwIt((short)0x6C0E);
            }else{
                apdu.setOutgoingLength((short)14);
                apdu.sendBytesLong(temp, (short)0, le);
            }
            break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

}

当它安装在使用 T=1 协议与用户通信的卡上时,您有:

Select Applet begin...
Select Applet successful.

Send: 00 00 00 00 00
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 01 00 00 00
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 02 00 00 00
Recv: 6C 0E
Send: 00 02 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 03 00 00 00
Recv: 6C 0E
Send: 00 03 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

并且当它安装在使用 T=0 协议与用户通信的卡上时,您有:

Select Applet begin...
Select Applet successful.

Send: 00 00 00 00 00
Recv: 6C 0E
Send: 00 00 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 01 00 00 00
Recv: 6C 0E
Send: 00 01 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 02 00 00 00
Recv: 6C 0E
Send: 00 02 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

Send: 00 03 00 00 00
Recv: 6C 0E
Send: 00 03 00 00 0E
Recv: 54 68 69 73 2D 49 73 2D 41 2D 54 65 73 74 90 00

正如您在上面所看到的,在这两种情况下,APDU 命令都带有 INS=0x2 or 0x03Le=0x00 return 0x6C0E。这是因为小程序是这样写的。但对于 INS=0x00 or 0x01,return 值取决于通信协议。对于 T=1,他们 return 0x6C0E,对于 T=1,他们 return 数据。