setATRHistBytes() 方法总是 returns false

setATRHistBytes() method always returns false

我编写了以下程序来将智能卡 ATR 中的 Historical Bytes 更改为,例如 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00。我使用 GPSystem.setATRHistBytes() 来设置历史字节。

请注意,0x00 0x00 ... 0x00 不是我用于历史字节的实际值,但我对其进行了审查。实际值是一个 15 字节的数组,等于另一张现有卡的历史字节。

package org.globalplatform;

import javacard.framework.*;
import org.globalplatform.GPSystem;

public class TestPrj extends Applet {

    public static final byte[] HIST_B= {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
    public static byte counter = (byte) 0x00;

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

    protected TestPrj() {
        register();
    }

    public void process(APDU apdu) {

        if (selectingApplet()) {
            if (counter == 0x03) {
                counter = (byte) (counter + 1);
                boolean changed = GPSystem.setATRHistBytes(HIST_B, (short) 0, (byte) HIST_B.length);
                if (changed) {
                    ISOException.throwIt((short) 0x9000);
                } else {
                    ISOException.throwIt((short) 0x6400);
                }

            } else {
                counter = (byte) (counter + 1);
            }
        }

        ISOException.throwIt((short) counter);
    }
}

在将上述程序转换为它的 CAP 文件并使用 Default Selected 权限安装小程序后(使用 GPSystem.setATRHistBytes() 需要),我仍然无法更改历史字节。

根据我收到的 APDU 响应,似乎 setATRHistBytes() 方法总是 returns false 表明历史字节未更新。

Connect successful.
Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Send: 00 A4 04 00 06 01 02 03 04 05 01
Recv: 00 01
Time used: 22.000 ms
Send: 00 A4 04 00 06 01 02 03 04 05 01
Recv: 00 02
Time used: 23.000 ms
Send: 00 A4 04 00 06 01 02 03 04 05 01
Recv: 00 03
Time used: 24.000 ms
Send: 00 A4 04 00 06 01 02 03 04 05 01
Recv: 64 00
Time used: 15.000 ms
Send: 00 A4 04 00 06 01 02 03 04 05 01
Recv: 00 05
Time used: 15.000 ms

注意01 02 03 04 05 01是我的小程序AID。

我的卡是 JCOP v2.4.2 R3,我尝试针对 GP 2.2.1 v1.6 和 GP 2.2 v1.4 API 进行编译。

setATRHistBytes(byte[] baBuffer, short sOffset, byte bLength) 需要一个作为输入缓冲区传递的全局数组 (baBuffer)。见 API documentation:

baBuffer - the source byte array containing the ATR historical bytes. Must be a global array.

全局数组是由 Java Card 运行时管理并可供所有小程序访问的特殊数组。在调用 process() applet lifecylce 方法期间,您可以预期对您的 Java Card applet 可用的唯一全局缓冲区是 APDU 缓冲区。

因此需要将HIST_B的内容复制到APDU缓冲区中,然后将APDU缓冲区传入setATRHistBytes():

byte[] buffer = apdu.getBuffer();
Util.arrayCopyNonAtomic(HIST_B, (short)0, buffer, (short)0, (short)HIST_B.length);
boolean changed = GPSystem.setATRHistBytes(buffer, (short)0, (short)HIST_B.length);