在 T=0 协议(protocol)的情况下,情况 1 和情况 2 APDU 的 TPDU 案例 3 和案例 4 APDU 相同, 因此,在来自智能卡的 T=0 协议(protocol)的情况下 无法区分情况 1 和 2 和 案例 3 和 4 APDU。 事实上,甚至无法区分 case 2 & 3 APDU,除非智能卡尝试读取数据字节,如果终端实际发送的APDU是case 2 APDU,这将导致失败。
但是,由于在 T=1 协议(protocol)中,TPDU 对应于 APDU 卡知道收到的 APDU 属于哪种情况。
问题是在 T=1 协议(protocol)的情况下,Java Card API 是否提供任何方法来:
- 知道收到的 APDU 是否是数据 APDU,因此可以安全地调用 setIncomingAndReceive();
- 从case 4 APDU中读取Le字节;
- 知道是否实际从终端接收到 Le 字节(在 APDU 缓冲区中的 P3 为 0x00 的模棱两可的情况下)。
最佳答案
1. know if the received APDU is data APDU and hence setIncomingAndReceive() can be called safely
这很有趣; getIncomingLength
似乎可以用于此目的:
the incoming byte length indicated by the Lc field in the APDU header. Return 0 if no incoming data (Case 1)
但它在异常描述中说:
APDUException.ILLEGAL_USE
ifsetIncomingAndReceive()
not called or ifsetOutgoing()
orsetOutgoingNoChaining()
previously invoked.
对于 setIncomingAndReceive()
你可以读到:
This method should only be called on a case 3 or case 4 command, otherwise erroneous behavior may result.
这里似乎有一个陷阱 22;我会询问我的资源之一,了解如何处理这个问题。同时,setIncomingAndReceive
或 getIncomingLength
不太可能(但并非不可能)针对情况 1 或 2 APDU 抛出异常。
2. read the Le byte from case 4 APDU
嗯,是的,通过读取 Nc 值,然后通过接收到的字节前进到 Le 字节或跟在命令后面的字节。但通常通过调用返回的 setOutgoing
更容易使用 Ne(实际长度而不是长度的编码):
Ne, the expected length of response
3. know if Le byte was actually received from the terminal (in the ambiguous case where P3 in APDU buffer is 0x00)
如果 P3 = 0x00,那么据我所知,P3 是 Le 字节。我不明白这是多么模棱两可。禁止lc有这个值。
注意事项:
- 大多数 APDU 命令都有预先描述的格式,因此您可以提前知道(在使用
process
方法处理 APDU 期间)您是否应该得到一个特定的案例 - 您可以抛出一个异常不要; - 我引用了 Java Card 3.0.5,因为它可以在线获取,而且它可以正确地区分 Nc、Lc、Ne 和 Le,但界面与早期版本并无不同。
关于JavaCard 和 T=1 协议(protocol) : distinguish between APDU cases,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43823009/