发送扩展 APDU 失败

Failed to send Extended APDU

我的 Java 卡上有一个大字节数组(它是 320 字节),我想在一个 APDU 响应中发送它的数据。

因此,我在我的小程序中实现了 ExtendedLength 接口,然后使用了以下程序:

package exPack;

import javacard.framework.*;
import javacardx.apdu.ExtendedLength;

public class testExtended extends Applet implements ExtendedLength {

    byte[] longData = {(byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09};

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new testExtended();
    }

    protected testExtended() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            ISOException.throwIt((short) 0x9001);
        }
        byte[] buffer = apdu.getBuffer();
        short toSend = (short) longData.length;
        byte counter = 0;
        while (toSend > 0) {
            Util.arrayCopyNonAtomic(longData, (short) (counter * 32), buffer, (short) 0, (short) 32);
            apdu.sendBytes((short) 0, (short) 32);
            toSend = (short) (toSend - 32);
            counter = (byte) (counter + 1);
        }
    }
}

问题是在行 apdu.sendBytes((short) 0, (short) 32); I 中收到 0x6F00 错误。我通过在这一行之前和之后抛出异常找到了错误点。

这是上面程序的响应:

Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Send: 00 A4 04 00 06 11 22 33 44 55 11 00
Recv: 90 01
Time used: 15.000 ms
Send: 00 00 00 00
Recv: 6F 00
Time used: 11.000 ms

有人可以帮我处理吗?

您的小程序抛出了未处理的异常,因为您调用了 sendBytes() 而没有先调用 setOutgoing()setOutgoingLength()

此外,我还没有真正计算 longData 的长度,但请确保它的长度是 32 字节的倍数,否则 Util.arrayCopyNonAtomic() 将抛出 ArrayIndexOutOfBoundsException 并使你的小程序抛出 6F00.

也许你可以这样试试:

    apdu.setOutgoing();
    apdu.setOutgoingLength(toSend);
    while (toSend > 0) {
        Util.arrayCopyNonAtomic(longData, (short) (counter * 32), buffer, (short) 0, (short) 32);
        apdu.sendBytes((short) 0, (short) 32);
        toSend = (short) (toSend - 32);
        counter = (byte) (counter + 1);
    }

或者更好,而不是执行 while 循环:

    apdu.setOutgoing();
    apdu.setOutgoingLength(toSend);
    apdu.sendBytesLong(longData, (short)0, toSend);

我让你的代码适用于我所有的卡片:

import javacard.framework.*;
import javacardx.apdu.ExtendedLength;

public class MiniApplet extends Applet implements ExtendedLength {

    byte[] longData = {(byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x00, (byte) 0x10, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09};

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new MiniApplet();
    }

    protected MiniApplet() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }
        short toSend = (short) longData.length;

        try {
            apdu.setOutgoing();
            apdu.setOutgoingLength(toSend);

            byte counter = 0;
            while (toSend > 0) {
                apdu.sendBytesLong(longData, (short) (32 * counter), (short) 32);
                toSend = (short) (toSend - 32);
                counter = (byte) (counter + 1);
            }
        } catch (Exception e) {
            if (e instanceof APDUException) {
                APDUException ae = (APDUException) e;
                short reason = ae.getReason();
                if (reason == APDUException.BAD_LENGTH)
                    ISOException.throwIt((short) 0x9990);
                else
                    ISOException.throwIt((short) 0x8887);
            } else {
                ISOException.throwIt((short) 0x8888);
            }
        }
    }
}

A​​PDU 日志:

=> 00 A4 04 00 08 F0 6D 69 6E 69 61 70 70 00  //different AID, not important
<= 90 00 //I got rid of your 9001, because it made my simulator mad

=> 00 00 00 00  //standard format                                       
<= 99 90 //APDUException.BAD_LENGTH thrown by apdu.setOutgoingLength(>256)

=> 00 00 00 00 00 00 00 //extended APDU format
<= 00 10 ... all your data, 320 bytes ... 90 00

如果此代码不能在您的卡上运行,则可能是您的 javacardx 包实现中的错误,您应该联系供应商。