【问题标题】:What is the structure of an application protocol data unit (APDU) command and response? [closed]应用协议数据单元 (APDU) 命令和响应的结构是什么? [关闭]
【发布时间】:2015-05-30 20:12:37
【问题描述】:

我正在努力学习 Java Card。我刚开始,还没有找到很多资源。我的第一个问题是如何理解 APDU 命令。 (如 ISO/IEC 7816-4 中定义的那些)

例如,如果我看到一个字节模式如 10101010 我如何理解它的含义,特别是确定 CLAINS 例如?

【问题讨论】:

  • 互联网上有很多参考资料。只需谷歌它,然后阅读,最后你会明白
  • 您好,您想了解更多信息吗?如果您有任何问题,请在我的回答下方的评论中问我...
  • APDU 规范在 ISO/IEC 7816-4 中。您可能想要获取最新版本的副本。不过它是付费软件。
  • 你也忘了接受这个问题的答案。看来您不想接受问题的答案。
  • 这个问题好像解决了。请将任何答案标记为已接受。

标签: javacard iso


【解决方案1】:

APDU 命令是以下形式的二进制数队列:

CLA | INS | P1 | P2 | LC |数据 |乐

前四个部分,即 CLAINSP1P2 在所有 APDU 命令中都是必需的每个都有一个字节长度。这些单字节长度的部分分别代表 Class、Instruction、Parameter1 和 Parameter2。

最后三个部分,即LcCDataLe是可选的。Lc是Nc的编码,也就是Nc的编码CDATA 字段的长度。 Le 是 Ne 的编码,然后是可能发送的最大响应数据的编码。根据这些部分的存在与否,我们为 APDU 命令提供了 4 种情况,如下所示:

  • 案例1:CLA | INS | P1 | P2
  • 案例2:CLA | INS | P1 | P2 | Le
  • 案例3:CLA | INS | P1 | P2 | Lc | Data
  • 案例4:CLA | INS | P1 | P2 | Lc | Data | Le

对于不同的命令和不同的小程序,CData 的长度是不同的。根据 CData 的长度(即 Lc)和可能发送的最大响应数据的长度(即 Le),我们必须输入 APDU 命令的类型:

  • Normal/Short APDU 命令,当 Lc Le 小于0xFF
  • 扩展长度 APDU 命令,当 Lc 和/或 Le 大于 0xFF

所以对于这些部分的长度,我们有:

Lc:1 个字节用于短 APDU 命令,3 个字节(它们指定此长度,因为它足够了)用于扩展 APDU 命令。

数据:不同的长度。

Le : 与 Lc 相同。


如何理解 APDU 命令?

答案:

当你编写一个applet 时,你指定你的applet 对不同的APDU 命令的响应,它将在未来接收到。 Card Manager 也是一个小程序。它支持的命令在您的卡的规格/数据表中定义。通常几乎所有卡都符合GlobalPlatformISO7816,因此它们必须支持这些文档中定义的那些强制性APDU 命令。例如,0xA4 在 ISO7816-4 标准中被定义为 SELECT FILE 命令,如果你看到像xx A4 xx xx 这样的 APDU 正在发送到 Card Manager,你可以断定它与 @ 相关987654331@.

请注意,您可以为不同小程序中的不同功能选择一个值。例如,Applet1 在接收00 B0 xx xx APDU 命令时会返回0x6990,而Applet2 在接收同一命令时会返回0x6991

小程序1:

public class SOQ extends Applet {

    private SOQ() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SOQ().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte buffer[] = arg0.getBuffer();
        
        if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 &&buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
            ISOException.throwIt((short)0x6990);
        }

    }

}

输出:

OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x90)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x90)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x90)

小程序2:

public class SOQ extends Applet {

    private SOQ() {
    }

    public static void install(byte bArray[], short bOffset, byte bLength)
            throws ISOException {
        new SOQ().register();
    }

    public void process(APDU arg0) throws ISOException {
        byte buffer[] = arg0.getBuffer();
        
        if(buffer[ISO7816.OFFSET_CLA] == (byte) 0x00 && buffer[ISO7816.OFFSET_INS] == (byte) 0xB0){
            ISOException.throwIt((short)0x6991);
        }

    }

}

输出:

OpenSC: opensc-tool.exe -s 00a404000b0102030405060708090000 -s 00B00000 -s 00B00
100
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 0B 01 02 03 04 05 06 07 08 09 00 00
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00
Received (SW1=0x69, SW2=0x91)
Sending: 00 B0 01 00
Received (SW1=0x69, SW2=0x91)

因此,您的问题(我如何理解 APDU 命令?)的最终简短答案是:

  • 您正在处理您的小程序?

    您自己定义了支持的命令及其形式!

  • 您正在处理另一个小程序(例如 Card Manager)?

    您需要该小程序的源代码或其支持的命令及其形式的文档,或该小程序符合的标准/规范(例如卡管理器全球平台)。

注意:我们的 APDU 响应几乎相同。

【讨论】:

  • 我认为指定的 CLA 和 INS 是二进制的,而不是十六进制的。 Lc是Nc的编码,也就是CDATA字段长度的编码。 Le 是 Ne 的编码,然后是可能发送的最大响应数据的编码。目前这在 Java Card 规范中也是不正确的 :)
  • 再次感谢您亲爱的 Bodewes 先生 :) 我更改了您提到的那部分。但我不明白您评论的第一句话(即:指定的 CLA 和 INS 是二进制的,而不是十六进制的。)。不仅价值很重要吗?我的意思是,正如您所知,Hex 或 Bin 只是视图的形式,并不重要。有人说我hex 数字的队列”,因为我几乎总是看到十六进制形式的 APDU 命令”。我错过了你评论中的一点吗?我想我没明白重点:)
  • 从您的回答中:“前四个部分,即 CLA 、 INS 、 P1 和 P2 在所有 APDU 命令中都是强制性的,并且每个部分都有一个字节长度(因此没有 CLA = 10101010 或 INS = 10101010)。” .我认为这有点误解。该问题首先以十六进制指定 APDU,现在以二进制指定 INS 和 CLA。如果它是二进制,则它是 CLA 和 INS 的有效编码,即使 BROY 只是记下了一些位。
  • @Maarten Bodewes 啊,你又是对的 :) 我将这些值视为0x10 0x10 0x10 0x10。我删除了那句话。谢谢。
  • 如何从终端向 JavaCardApplet 发送命令?@Abraham
【解决方案2】:

恐怕这样一本“完整”的电子书根本就不存在。老实说,我认为根本没有必要。如果您了解基本的 Java 语法,您会发现 JavaCard 非常容易学习(虽然使用起来很烦人)。 Javacard 中缺少所有常见的困难内容(线程、GUI、IO、注释、模板、数据库……),而且标准库非常有限,您将能够在几天内学习它们。

那里有一些不错的教程:

http://www.oracle.com/technetwork/java/embedded/javacard/overview/index.html http://javacard.vetilles.com/tutorial/

还有一个非常好的问题:

How to get started with Java Cards?

回答您的问题:JavaCard 只是一种用于编写称为小程序的智能卡应用程序的语言。它处理所有应用程序逻辑,但不指定 APDU 格式。那是因为 JavaCard 不是唯一的智能卡技术。 APDU 格式在 ISO7816 标准中指定,我强烈建议您通读。它不是免费下载的,但您可以在这里找到最重要的部分:

http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_5_basic_organizations.aspx

您会发现,您的 APDU 命令包含一个标头:

00A404000E

还有一个数据部分:

63616C63756C61746F722E617070.

标题指定应该调用什么函数:

00 - 类字节(CLA,00 表示“发送到逻辑通道 0 的行业间命令”)

A4 - 指令字节(INS,A4 表示“选择小程序命令”)

04 - 参数 1 (P1)

00 - 参数 2 (P2)

0E - 数据部分的长度(Lc)

并且数据部分包含应选择以供将来使用的小程序的标识符(在您的情况下,它是一个 ASCII 编码字符串“calculator.app”顺便说一句)。

【讨论】:

  • 如何理解 CLA 或 INS 的任何值? Internet 上没有格式正确的文档。例如,如果 CLA = 10101010,我如何理解其含义?或者,如果 INS = 10101010?
  • @BROY 查看本文档中的第 5.4.1 和 5.4.2 章:cardwerk.com/smartcards/…
  • 很好的答案和信息量。 “选择”命令不是使用十六进制数字 AID 而不是字母字符串吗?如果我错了,请纠正我。谢谢。
  • @typelogic 是的,字母字符串使用 ASCII 编码为字节。
猜你喜欢
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 2013-04-06
  • 2012-07-29
  • 2017-05-16
  • 2013-07-02
  • 2013-01-28
相关资源
最近更新 更多