Safe Max Java 卡 APDU 数据命令和响应大小

Safe Max Java Card APDU Data Command and Respond Size

Java 卡 APDU 中推荐的数据字段大小是多少?陈志群的Java Card Technology for Smart Cards: Architecture and Programmer's Guide书中提到乐域最大允许255。

我们是否将其解释为 APDU 命令:

|<----------------------- 255 Bytes total ------------------------>|
|<- CLA -><- INS -><- P1 -><- P2 -><- Lc -><---- DATA ----><- Le ->|

因此,如果 CLA、INS、P1、P2、Lc、Le 都是 1 个字节,我们应该假设我们只能安全地将 249 个字节设置到 DATA 区域?

对于 APDU 响应,我们要解释:

|<----------------------- 258 Bytes total ------------------------>|
|<-------------------------- DATA ------------------------><- SW ->|

响应数据可以安全地设置为 256 字节和 2 字节的 SW,并且由数据响应和 SW 组成的响应总计为 258 字节?

考虑到我们必须面对可能无法进行链接并且我们必须自己手动处理数据流的情况,安全地发送和接收数据块还有哪些其他注意事项?

Lc 和 Le 字节最多可以向 hold/request 0xFF 字节发送信号。因此,对于 Case 4 命令 APDU,您有 6(header+lc+le) + 0xFF = 261 字节。对于最大响应,您有 256 字节 + 2(状态字)= 258 字节。这就是标准所建议的。但是,不同的硬件令牌可能有不同的实现,因此这可能不是 100% 准确。如果您需要更多数据,则需要实施 ExtendedLength。

AFAIK Le 字段允许 1-256 字节(255 限制用于 Lc)引用 ISO 7816-3:

Case 2S ⎯ The short Le field consists of C(5) encoding Ne from 1 to 256 ('00' means the maximum, 256)....
....
Case 4S ⎯ ...The short Le field consists of C(6+Nc) encoding Ne from 1 to 256 ('00' means the maximum, 256)....

(而且符合你的"Response APDU"长度256+2,可能是打错了)

255 字节的限制是针对 "Command APDU" 的数据部分。所以对于整个非扩展长度"Command APDU",限制应该是5+255+1

所有这些限制都在 ISO 7816-3 中进行了精确定义——请看这里。


注意,javacard 的 APDU 缓冲区 可能 更小。来自 APDU class:

的 javadoc

The buffer length (meaning APDU buffer) must be at least 133 bytes ( 5 bytes of header and 128 bytes of data)

因此,要读取超过 128 字节的传入数据,您可能需要调用 APDU.receiveBytes() 来获取不适合的其余字节。

相同的可能适用于发送数据(即APDU.sendBytes()可能需要发送更长的数据)。


对于应用程序级别的框架,我知道这些方法(可能会鼓舞人心):

  • ISO 7816-4(使用 CLA 中的位 5)

  • 全球平台(使用P1的最高位表示更多blocks/last块用于某些命令)

  • EMV CPS(在数据中使用明确长度的 STORE DATA 命令)

Lc 和 Le 字段编码最大数据大小 Nc 和 Ne。对于正常长度的 APDU,Nc 最大为 256(Lc = 00h,一种特殊情况),Ne 最大为 255(Le = FFh),其中 Lc 和 Le 字段各为 1 个字节。 Nc不包括4字节header,Lc编码或Le编码。 Ne 指定的大小不包括 2 字节(16 位)状态字。


当然可以为特定命令发送更多数据。如果卡支持,您可以使用扩展长度。有关详细信息,请参阅 ISO/IEC 7816-4。

扩展长度使用 16 位有效 Lc 和 Le 大小。它最多可以支持 64KiB 用于 Nc(有效部分为 0000h)和 64KiB - 1 用于 Ne(Le 的有效部分 = FFFFh)。但是,由于使用signed short,Java Card在使用扩展长度时被限制为Nc = 32KiB - 1 和Ne = 32KiB - 1。通常你会 运行 out buffer space 很久以前,这取决于卡实现如何处理。扩展长度也会增加 header、Lc 和 Le 开销。

命令链接比较棘手,因为您必须自己实施。它基本上多次发送相同的命令,使用 CLA 字节中的链接位来指示后面将有更多命令,直到该位重置为零。


当然,您可以自己使用命令执行任何操作。所以你可以,例如定义一个文件并使用多个 WRITE BINARY 命令写入该文件。如何定义这些命令完全取决于您。


当使用安全消息传递时,我不会讨论最大大小。它可以进行一些非常有趣的计算,尤其是如果使用 BER 编码来实现安全消息传递。