Java卡发送数据不获取数据APDU

Java Card to send data without get data APDU

我是这个领域的新手,如果我的问题很幼稚,请原谅我。

我想发行一张 Java 卡,它有一个自动 select 小程序,几乎所有 APDU 都将在这个小程序中处理。我需要这个小程序将数据发送到 CAD,而不是使用 Java 卡标准中的常用格式(即不发送 0x61 0xbytesToRead 并等待 0x00 0xc0)。
例如,我想发送 0x23 字节以响应 0xA0A40000027F20,这几乎是一个 SELECT 命令,但第一个字节错误!

那么这有可能吗?如果可能的话,请告诉我怎么做。

谢谢。

是的,这是可能的。为了实现您的目标,您有以下两个步骤:

  1. 您必须将小程序设置为默认 selected。
  2. 您必须 return 接收此命令的一些数据,and/or 接收 SELECT APDU 命令。

第一步,如回答here:

这取决于卡片 - 并非所有卡片似乎都支持在安装后将小程序设为默认值。但是您可以使用具有 --make-default 选项的 Java 的开源 GlobalPlatform 工具:

java -jar gp.jar --make-default A000100201100001

IIRC JCOP 是实际支持它的卡之一。

第二步,如回答

我猜你正在处理 "if selectingApplet() then return" 的 "good practice"?您需要处理传入的 APDU 而不是简单的 return。 您可以 return 数据到 select 正常方式,但如果 select 成功,请注意 return 0x9000。

必须是这样的:

public void process(APDU apdu)
    { 
       byte[] buf = apdu.getBuffer();
       if (selectingApplet())
          { 
          //send the data in buffer return;
          }
    } 

更新:

在此答案下方回答您的评论:

我写了下面的程序:

package test;

import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.Util;

public class Test extends Applet {

    public static final byte[] res = { (byte) 0x00, (byte) 0x00, (byte) 0x3B,
            (byte) 0xAD, (byte) 0x3F, (byte) 0x00, (byte) 0x01, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
            (byte) 0xB3, (byte) 0x03, (byte) 0x06, (byte) 0x04, (byte) 0x00,
            (byte) 0x83, (byte) 0x8A, (byte) 0x83, (byte) 0x8A, (byte) 0x00,
            (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD,
            (byte) 0x00, (byte) 0x00, (byte) 0x3B, (byte) 0xAD, (byte) 0x2F,
            (byte) 0x06, (byte) 0x02 };

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

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

        byte[] buf = apdu.getBuffer();

        if (buf[ISO7816.OFFSET_CLA] == (byte)0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xA4 && buf[ISO7816.OFFSET_P1] == (byte) 0x00&& buf[ISO7816.OFFSET_P2] == (byte) 0x00 
                && buf[ISO7816.OFFSET_LC] == (byte) 0x02 && buf[ISO7816.OFFSET_LC + 1] == (byte) 0x7F  && buf[ISO7816.OFFSET_LC + 2] == (byte) 0x20) {
            ISOException.throwIt((short) 0x9F23);
        } else if (buf[ISO7816.OFFSET_CLA] == (byte) 0xA0 && buf[ISO7816.OFFSET_INS] == (byte) 0xC0  && buf[ISO7816.OFFSET_P1] == (byte) 0x00 
                && buf[ISO7816.OFFSET_P2] == (byte) 0x00  && buf[ISO7816.OFFSET_P2+1] == (byte) 0x23 ) {
            Util.arrayCopyNonAtomic(res, (short) 0, buf, (short) 0, (short) 35);
            apdu.setOutgoingAndSend((short) 0, (short) 35);

        } else {
            ISOException.throwIt((short) 0x9090);
        }
    }
}

然后我默认安装它 selected 小程序:

CommandLine> gp -install e:\soq.cap --default

CommandLine>

然后我向它发送 APDU 命令:

CommandLine> OSC.exe -s A0A40000027F20 -s a0c0000023
Using reader with a card: ACS CCID USB Reader 0
Sending: A0 A4 00 00 02 7F 20
Received (SW1=0x9F, SW2=0x23)
Sending: A0 C0 00 00 23
Received (SW1=0x90, SW2=0x00):
00 00 3B AD 3F 00 01 00 00 00 00 00 16 B3 03 06 ..;.?...........
04 00 83 8A 83 8A 00 03 00 00 3B AD 00 00 3B AD ..........;...;.
2F 06 02                                        /..

看来如你所愿。