JavaCard 连接在耗时处理时中断

JavaCard connection breaks on time-consuming processings

我正在编写一个 JavaCard 2.2.1 小程序,它对输入数据进行大量数学处理并将结果 return 发送到计算机。我的代码有很多 forwhile 循环。问题是,当我从 PC 调用卡时,与卡的连接没有等待卡完成所有过程,并且 return 出现 PC/SC 协议错误。我在 C# 中使用 PCSC library 从 PC 与卡通信,并收到此错误:检测到与智能卡的通信错误。

为了重现这个问题,我准备了一个带有一些虚拟计算的测试小程序:

package my.testapplet;

import javacard.framework.*;

public class TestApplet extends Applet
{

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

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

        byte[] buf = apdu.getBuffer();
        short result = 0;
        if (buf[ISO7816.OFFSET_CLA] == ISO7816.CLA_ISO7816) {
            switch (buf[ISO7816.OFFSET_INS])
            {
            case (byte)0x00:
                {
                    short temp1 = 0;
                    short temp2, temp3 = 0;
                    while(temp1 < 30000) {
                        temp1++;
                        temp2 = 0;
                        while(temp2 < 30000) {
                            temp2++;
                            if(temp2 > 0) {
                                temp3 = (short)(temp1 * 2 + 1);
                            }
                        }
                    }
                    result = 100;
                }
                break;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }

            buf[0] = (byte) (result & 0xff);
            buf[1] = (byte) (result >>> 8);

            apdu.setOutgoingAndSend((short) 0, (short) 2);
        } else {
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }

}

我已经在 3 种不同的 java 卡模型(来自不同供应商)上测试了这个小程序,所有结果都相同。另外我要注意,运行卡模拟器中的代码没有问题。问题发生在真正的物理 java 卡上。 java 卡上的虚拟机似乎错误地将 运行 代码中的某些循环检测为无限循环,并中断了连接。

我不知道这个问题。 java 卡有类似的经历吗?知道为什么 java 卡上会出现此行为以及如何解决吗? java 卡上是否有任何特殊的 instruction/configuration 来禁用此行为并等待 java 卡准备好并 return 结果?

WTX(等待时间延长)是必要的,以通知 reader 它必须等待,因为还没有响应,否则它确实会超时并断开连接。在 APDU 层看不到 WTX,因为它在较低级别 T=0、T=1 和 T=CL 协议级别上运行。可以看出它与 TLS 心跳或其他保持传输层活动的消息具有类似的作用。顺便说一句,标准等待时间可以通过ATR配置。

较新的卡通常能够自动处理 WTX,即使该功能不需要实现。较旧的卡通常只为可能需要比完成时间更长的特定 API 调用启用 WTX 扩展。显然,RSA 密钥对生成是这里的主要罪魁祸首,但启动时的垃圾收集和安装 Applets 等其他操作也可能使用 WTX。

如果您有更长的 运行 方法,那么您可能必须定期自己发布 WTX。您希望在相对较短的时间内发布 WTX 以允许更细粒度的控制 - 如果您可以正确估计所需的时间。最好您的协议也包含细粒度的 APDU,以便尽可能少地使用 WTX。正如 M. Mahdipour 所发现的,发行 WTX 可能会导致卡片 reader 永远等待,因此并非完全没有风险(请参阅问题下方的评论)。

无论如何,让Java卡发送低级WTX消息的方法是静态APDU.waitExtension()方法。