2

我编写了以下程序,将智能卡 ATR 中的历史字节更改为,例如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()方法似乎总是返回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 进行编译。

4

1 回答 1

4

setATRHistBytes(byte[] baBuffer, short sOffset, byte bLength)需要一个作为输入缓冲区 ( baBuffer) 传递的全局数组。请参阅API 文档

baBuffer- 包含 ATR 历史字节的源字节数组。必须是全局数组。

全局数组是一个特殊的数组,它由 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);
于 2015-12-22T08:17:56.537 回答