使用READ BINARY读取超过256个字节

rre*_*ach 8 java smartcard

我正在尝试使用javax.smartcardio 读取智能卡(德语Gesundheitskarte)

在EF"PD" 的定义中,其长度指定为850字节.内容应该是这里指定的gzip压缩的ISO5589-15编码XML字符串

作为我发送的CommandAPDU

00 B0 00 00 00
Run Code Online (Sandbox Code Playgroud)

得到前256个字节.发送后

00 B0 00 FF 00
Run Code Online (Sandbox Code Playgroud)

我得到接下来的256个字节.

但我怎么得到其余的?

我怎么知道二进制数据何时结束?

德国规范第1部分 | 德国规范第2部分

pb2*_*b2q 10

READ BINARYAPDU允许2个字节用于文件偏移,以P1和P2编码,并使用Le作为READ BINARY响应中的字节数.P1是高字节或最高有效字节.然而,保留P1的最高位以指示P1是否还包含短文件标识符.0如果您已经在读取文件,它应保持有效值,最大偏移量为32Ki - 1.

我无法阅读您已链接的规格,但我们假设READ BINARY您的卡上的APDU工作方式相同.

您读取前256个字节的命令似乎是正确的,注意这Le==0x00表示读取了256个字节.

要读取从偏移量256,512等开始的字节,请开始递增P1,例如:

00 B0 01 00 00
00 B0 02 00 00
00 B0 03 00 00
Run Code Online (Sandbox Code Playgroud)

从偏移量257(0x101)开始读取256个字节:

00 B0 01 01 00
Run Code Online (Sandbox Code Playgroud)

偏移量600(0x258):

00 B0 02 58 00
Run Code Online (Sandbox Code Playgroud)

在你的代码中,如果你使用Java int来存储偏移量,你通常最终会用这样的东西递增P1:

int offset;
int P1, P2;

while (continueReading)
{
    // ...
    P1 = (offset >> 8) & 0xFF;
    P2 = offset & 0x00FF;
    // ...
    // send APDU
}
Run Code Online (Sandbox Code Playgroud)

如何指示文件的大小取决于实现.通常,您可以从EF(00 A4 00 00 02 fileId)上的SELECT返回的文件控制信息(FCI)结构中获取文件大小.但是,文件的大小也可以嵌入文件的内容中.如果可能,您不应该依赖状态字来告诉您文件的大小.


增加:Le,Ne和奇INS

重要的是,您只需使用响应数据(RDATA)中实际接收的字节数来增加偏移量.注意,如果P3 = Le,则Le编码Ne,这是响应数据的最大大小.你可能收到的不到那个.

如果文件大小为32Ki或更大,则需要使用READ BINARY和奇数INS(B7)来读取32Ki以上的数据.在这种情况下,RDATA也可能包含开销.显然, - 反过来 - 可能会影响偏移计算和读取到文件末尾的计算.


Maa*_*wes 5

偏移量为P1&P2,尽管最高位用于表示您要选择具有给定SFI的内容.所以你也可以使用P1字节.之后你将不得不走向READ BINARY with an odd INS(B1).

因此,您可以使用正常读取二进制读取最多2 ^ 15 - 1个字节.这是32Ki - 1.当然还有几个字节,因为APDU返回了字节.

我总是使用以下方法从智能卡中读出文件:1确定文件大小,例如使用通过FILE ID(00 A4 02 00 02 ${FILE_ID})返回的FCI(文件控制信息)返回,您需要解析响应.然后每次增加偏移量返回的字节数.永远不要求超过最大文件大小,因为大多数卡的行为不同,没有定义或只是明显错误).

高级主题:如果使用READ BINARY with ODD INS,则每次增加偏移量时都需要减去DO的标题.在这种情况下,读到最后会变得有点麻烦,因为您需要将标头的开销添加到Le字节中.

  • 请注意,此信息可在ISO 7816-4中找到.它是付费软件,但通常你可以非法地找到规范而无需成本,或者你可以从其他libs中提取信息.如果您正在创建商业软件,请购买规格! (2认同)