扩展 APDU 和 T=0/1 通信协议

Posted

技术标签:

【中文标题】扩展 APDU 和 T=0/1 通信协议【英文标题】:Extended APDUs and T=0/1 communication protocols 【发布时间】:2015-03-04 13:39:22 【问题描述】:

我有一张 JCOP V2.4.2 R3 java 卡,在其数据表“该卡同时支持 T=1T=0 通信协议”中提到它

我还有一个 ACR38 智能卡读卡器,它支持 T=0 和 T=1 协议。 (我与一张卡成功T=0通信,与这张卡成功T=1通信。)

我编写了以下程序并上传到卡上以发送和接收扩展 APDU:

package extAPDU;

import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacardx.apdu.ExtendedLength;

public class ExAPDU extends Applet implements ExtendedLength 

    private ExAPDU() 
    


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

    public void process(APDU arg0) throws ISOException 
        short number = arg0.setIncomingAndReceive();
        arg0.setOutgoingAndSend((short)0, (short)(number+7));
    


在 CAD 方面,我使用 python 脚本将不同的 APDU 发送到卡。问题是:

1-为什么我不能用T=0协议开始通信(虽然提到卡支持这个协议):

python 脚本:

from smartcard.scard import *
import smartcard.util
from smartcard.System import readers
from smartcard.CardConnection import CardConnection

r=readers()
print r
connection =r[0].createConnection()
connection.connect(CardConnection.T0_protocol)

normalCommand=[0x00,0xa4,0x04,0x00,0x06,0x01,0x02,0x03,0x04,0x05,0x06]
data,sw1,sw2=connection.transmit(normalCommand)
print "SW for Normal Command:"
print data,hex(sw1),hex(sw2)

输出:

>>> ================================ RESTART ================================
>>> 
['ACS CCID USB Reader 0']

Traceback (most recent call last):
  File "C:\extAPDU.py", line 13, in <module>
    connection.connect(CardConnection.T0_protocol)
  File "D:\PythonX\Lib\site-packages\smartcard\CardConnectionDecorator.py", line 54, in connect
    self.component.connect(protocol, mode, disposition)
  File "D:\PythonX\Lib\site-packages\smartcard\pcsc\PCSCCardConnection.py", line 118, in connect
    raise CardConnectionException('Unable to connect with protocol: ' + dictProtocol[pcscprotocol] + '. ' + SCardGetErrorMessage(hresult))
CardConnectionException: Unable to connect with protocol: T0. The requested protocols are incompatible with the protocol currently in use with the smart card. 
>>> 

2- 为什么卡不能在 T=1 协议的扩展形式中使用 Select APDU 命令正常工作:

python 脚本:

from smartcard.scard import *
import smartcard.util
from smartcard.CardConnection import CardConnection
from smartcard.System import readers

r=readers()
print r
connection =r[0].createConnection()
connection.connect(CardConnection.T1_protocol)

normalCommand=[0x00,0xa4,0x04,0x00,0x00,0x00,0x06,0x01,0x02,0x03,0x04,0x05,0x06]
data,sw1,sw2=connection.transmit(normalCommand)
print "SW for Normal Command:"
print data,hex(sw1),hex(sw2)

输出:

>>> ================================ RESTART ================================
>>> 
['ACS CCID USB Reader 0']
SW for Normal Command:
[] 0x67 0x0
>>> 

我想我误解了这个概念,我将扩展 APDU 与 T=1T=0 协议混为一谈!

每一个T=1 兼容的智能卡,都可以发送和接收扩展APDU吗?而且我们不能通过T=0 协议发送和接收扩展的APDU?如果我们想向Security Domain发送Extended SELECT APDU命令,SD必须实现ExtendedLength接口?

对于扩展 APDU 传输有什么要求?

    T=1 兼容读卡器 T=1 兼容的智能卡 一个实现ExtendedLength接口的小程序

对吗?

我对智能卡中的扩展兼容性和T=0/1 兼容性感到非常困惑。任何光线都会受到赞赏。

请注意,我可以使用T=1 协议成功地将扩展 APDU 发送到上述小程序!

【问题讨论】:

【参考方案1】:

Q1:可以更改协议。 hte 卡支持哪些协议的信息通过 ATR/ATS 收发。然后终端可以决定使用哪一个。因此,协议是否可选取决于您的终端外壳。对于 JCOP Shell,这是/change-protocol。 不过一般不推荐T=0。

Q2:如果您通过发送 ATR/ATS 启动卡,则卡管理器处于活动状态,仅支持全球平台命令。全球平台不支持扩展长度。通过发送一个 Select 命令(因此必须是简单的长度),applet 被选中,并且实际的 Select 命令也被转发到 Applet 的 process() 方法(并且可以通过 selectingApplet() 方法检测到)。现在您在 Applet 中,您可以发送任意数量的扩展长度命令。您可以通过将您的小程序安装为默认选择来绕过初始的 Non-Extended-Length-Select。

【讨论】:

为什么他不能用T=0协议开始通讯呢?我可以要求看看另一个答案下的最后一条评论吗? PySCard库中提供了选择通信协议的选项,不代表协议是可选择的吗? (我的意思是:connection.connect(CardConnection.T1_protocol)connection.connect(CardConnection.T0_protocol))? T0启动失败,和读卡器有关吗? (ACR38) 最后一个问题:制造商必须在数据表中明确提及扩展长度兼容性吗?或者用户可以根据 Java Card 平台版本和 T-1/0 兼容性来判断是否兼容?换句话说:卡是否可以兼容 Java Card 3 平台,但不支持扩展长度的 APDU 传输?或者是否可以 T=1 兼容,但不支持扩展长度?或者是否有可能是 Java Card 3 平台和 T=1 兼容,但不支持扩展 lentgh?这些参数之间有什么关系:) 制造商文件说明是否支持扩展长度。对于 JCOP 242R3,我非常确定支持 ExtLength。我不知道 PySCard,也没有使用过 ACR38(谣言说它很糟糕)。可能是驱动问题。我们要运行 T=0 协议吗? Well ExtendedLength 只是一个可选功能,因此您一般不能发表任何声明。一般来说,我会说有很多规范,而且大部分都是可选的,最终取决于硬件/软件的开发人员他们选择支持什么。因此,您必须定义系统的某些部分并阅读开发者文档。我再也不能说那个sry了:P【参考方案2】:

并非每张兼容 ISO 的卡都可以发送和接收扩展 APDU。这在很大程度上是一个可选功能。您的卡实现了哪个版本的 JCOP?

至于 T=0 与 T=1:当一张卡表明支持两种协议时,由读卡器决定使用哪一种。如果是 PC/SC 读卡器,则无能为力。

更新到添加:现在你说你可以成功的向上面的小程序发送扩展的APDU。因此,该卡似乎确实支持扩展 APDU。但如果 Le 不存在,可能内置的 SELECT 命令不允许使用它们,因为它们没有用例。

【讨论】:

我更新了这个问题。它是一张JCOP V2.4.2 R3 卡。我的读卡器是支持两种协议的ACR38。所以读卡器和读卡器都支持T=0。那为什么我不能用 T=0 协议开始通信呢? @Am1r:所以 ACR38 读卡器看到卡支持这两种协议,并决定自己使用 T=1。您对此无能为力。 谁选择传输协议?程序员还是读者?! JCOP OS 的实现者更难(他们也是程序员!) @Abraham:我建议你问问 Paul Bastian。从他的回答来看,他对JCOP的了解比我多!【参考方案3】:

Java Card 本身已经处理了 T=0 特定的命令,因此 T=0/T=1 APDU 对程序员来说几乎是一样的。当然存在差异,但这些在 APDU 类中得到了很好的解释。

T=0 是基于字节的协议,而 T=1 使用底层的帧。大多数 T=0 的卡不支持扩展长度。请注意,要获得扩展长度功能,需要实现javacardx.apdu.ExtendedLength 标记接口。

JCOP 卡可以配置为使用 T=0/T=1/T=CL 等。但是,您需要访问卡(可能还有用户手册)来配置卡。 Java Card API 不包含任何用于更改冷或暖 ATR 中对协议或传输协议参数的支持的命令。

关于延长长度的要求,您是正确的。请注意,现在可能很难找到不支持 T=1 的读卡器。 T=0 是旧协议,应该首选 T=1。

【讨论】:

谢谢你亲爱的马丁。您知道为什么我不能选择具有普通 APDU 和 T=0 协议(即使用第一个 python 程序)的小程序,而我很确定卡支持 T=0 通信协议吗? 该卡似乎仅配置为 T=1。您可以尝试显示卡的 ATR。如果配置正确,那么它应该显示支持的协议,如果我没记错的话。 我解析了 ATR,我认为你是对的。 (smartcard-atr.appspot.com/…) 顺便说一句,您使用过 CardTool 吗? (ACS公司专用的ACR38阅读器工具) 不,在我没有亲自遇到过的所有读者中(对于有一天或另一天最终出现在我办公桌上的读者数量而言,这有点令人惊讶)跨度>

以上是关于扩展 APDU 和 T=0/1 通信协议的主要内容,如果未能解决你的问题,请参考以下文章

SIM通信协议-传输协议

IM (二):数据通信协议的选择

什么是通信网络协议

RocketMQ通信协议

82.基于tcp和udp协议的简单通信套接字编程

Mysql通信协议