【问题标题】:setATRHistBytes() method always returns falsesetATRHistBytes() 方法总是返回 false
【发布时间】:2015-12-21 07:41:25
【问题描述】:

我编写了以下程序来将我的智能卡的 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 进行编译。

【问题讨论】:

  • 您的历史字节是否遵循结构规则?见cardwerk.com/smartcards/…。我不确定这是否能帮助你,但绝对值得一试,我希望......
  • @vojta 当我从HIST_B 字段中另一张卡的历史字节复制和粘贴时,我可以断定我遵循了结构规则吗? (0x00 0x00 .... 0x00 不是我想要设置的真实值。我对其进行了审查。实际上它是一个 15 字节的数组。)
  • @vojta 在我的包中加载错误版本的 globalPlatform .java 文件会导致此问题吗? (例如加载 GP 2.2 版本 1.3 .java API 文件而不是 GP 2.2 版本 1.1 .java API 文件)
  • 你使用什么API实现?你的卡是什么类型的?
  • 必须将全局数组传递给setATRHistBytes()。尝试将 HIST_B 的内容复制到 APDU 缓冲区(这是调用 process 方法期间唯一可用的全局数组),然后将 APDU 缓冲区传递到 setATRHistBytes()

标签: smartcard javacard globalplatform


【解决方案1】:

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

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);

【讨论】:

  • 谢谢罗兰先生。我认为这种方法(setATRHistBytes())只能更改冷重置 ATR。是否也有任何方法可以更改热重置 ATR?
  • 还有一个问题:当我删除我的小程序时,ATR 会变成它以前的值还是固定为我配置的这个新值?
  • 嗯,我试过了。对于我的卡 (JCOP V2.4.2 R3) 删除小程序,导致 CM 撤销之前的 ATR。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多