智能卡读卡器相关技术简介

1. PC/SC

PC/SC,指个人计算机/智能卡,它是为计算机访问智能卡而制定的一个标准架构。PC/SC的主要优点是PC的应用程序在与智能卡进行通信时无需了解读卡器的技术细节,而且PC的应用程序可以与任何符合PC/SC标准的读卡器协同工作。目前windows系统和linux系统都实现了这个标准。

 下图是windows系统中,基于PC/SC标准的智能卡子系统构成组件(摘自: MSDN Library: Platform SDK: Smart Card)

 

我们的PC/SC兼容的sim卡读写程序和apdu命令发送程序,使用win32 API操作智能卡,基本步骤如下:

1. 与智能卡资源管理器建立连接:

SCARDCONTEXT    hSC;
LONG            lReturn;
// Establish the context.
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
                                NULL,
                                NULL,
                                &hSC);

2. 列出读卡器:

LPTSTR          pmszReaders = NULL;
LPTSTR          pReader;
LONG            lReturn, lReturn2;
DWORD           cch = SCARD_AUTOALLOCATE;

// Retrieve the list the readers.
// hSC was set by a previous call to SCardEstablishContext.
lReturn = SCardListReaders(hSC,
                           NULL,
                           (LPTSTR)&pmszReaders,
                           &cch );

3. 使用列出的读卡器名称与之连接:

SCARDHANDLE     hCardHandle;
LONG            lReturn;
DWORD           dwAP;

// Connect to the reader.
// hContext is a SCARDCONTEXT previously set by
// a call to SCardEstablishContext.
lReturn = SCardConnect( hSc,
                        L"QWY Reader 0",
                        SCARD_SHARE_SHARED,
                        SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
                        &hCardHandle,
                        &dwAP );

4. 发送APDU:

// Transmit the request.
// lReturn is of type LONG.
// hCardHandle was set by a previous call to SCardConnect.
// pbSend points to the buffer of bytes to send.

/*

For T=0, the data parameters are placed into the pbSendBuffer according to the following structure:

struct {
    BYTE
        bCla,   // The instruction class
        bIns,   // The instruction code
        bP1,    // Parameter to the instruction
        bP2,    // Parameter to the instruction
        bP3;    // Size of I/O Transfer
} CmdBytes;

*/

// dwSend is the DWORD value for the number of bytes to send.
// pbRecv points to the buffer for returned bytes.
// dwRecv is the DWORD value for the number of returned bytes.
lReturn = SCardTransmit(hCardHandle,
                        SCARD_PCI_T0,
                        pbSend,
                        dwSend,
                        NULL,
                        pbRecv,
                        &dwRecv );

5. 退出:

// Terminate the connection.
// lReturn is a LONG variable.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardDisconnect(hCardHandle,
                          SCARD_LEAVE_CARD);
// Free the context.
// lReturn is of type LONG.
// hSC was set by an earlier call to SCardEstablishContext.
lReturn = SCardReleaseContext(hSC);

2. PC/SC兼容的驱动程序

windows系统中,智能卡子系统在核态也提供了相关的库函数,帮助智能卡读卡器制造商写PC/SC兼容的驱动程序。下图描述了智能卡子系统提供的相关组件(摘自: Window DDK: Smart Card Devices):

 

 智能卡子系统提供的函数帮助实现:

 

 下面是智能卡子系统提供的核态函数的完整列表,从函数名称可以对应到上面列出的功能:

SmartcardInitialize

SmartcardCreateLink
SmartcardDeviceControl

SmartcardUpdateCardCapabilities
SmartcardT0Reply
SmartcardT0Request
SmartcardT1Reply
SmartcardT1Request

SmartcardRawReply
SmartcardRawRequest

SmartcardLogError
SmartcardAcquireRemoveLock
SmartcardReleaseRemoveLock
SmartcardDeleteLink
SmartcardExit

智能卡资源管理器通过IOCTL -> SmartcardDeviceControl 访问驱动程序,智能卡子系统已经实现的IOCTL code(如:IOCTL_SMARTCARD_GET_ATTRIBUTE)由SmartcardDeviceControl 直接调用,智能卡子系统同时定义了一些必须由智能卡驱动厂商实现的IOCTL code,通过回调函数的方式,由驱动厂商注册。如我们的驱动中注册了以下几个回调函数:

 smartcardExtension->ReaderFunction[RDF_TRANSMIT] = USCRTransmit;
 smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = USCRSetProtocol;
 smartcardExtension->ReaderFunction[RDF_CARD_POWER] = USCRPower;
 smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = USCRCardTracking;

其他几个RDF_CARD_EJECT RDF_IOCTL_VENDOR RDF_READER_SWALLOW是可选实现。

驱动程序处理IOCTL过程如下图:(摘自: Window DDK: Smart Card Devices)

 

 

回调函数 USCRTransmit USCR...利用USB子系统提供的函数按照既定的协议(如CCID,由USB组织指定)与智能卡读卡器通讯。

3.智能卡读卡器

1. CCID(USB Chip/Smart Card Interface Devices)

 

 摘自 Device Class Specification for USB Chip/Smart Card Interface Devices

CCID由USB组织制订,目的是提供USB智能卡读卡器类设备的标准协议,厂商按照此协议制造的智能卡读卡器可以利用标准的智能卡读卡器类设备驱动程序。目前windows,linux等系统均由CCID类设备驱动程序,windows系统可以通过driver update得到(插入CCID兼容的读卡器,选择driver update即可)。

CCID的不足:

CCID要求USB必须是全速(full speed)设备,至少有bulk out和bulk in,以及默认的 control pipe 。

 微软驱动目前的缺点:

 虽然CCID标准规定interrupt pipe 为可选节点,但是没有interrupt pipe,目前微软的驱动不能正常工作。

 http://support.microsoft.com/kb/919922

2. ISO7816

详见 http://download.laogu.com/download/7816.chm

 

参考:

MSDN Library

Windows DDK

http://www.gemplus.com.cn/techno/pcsc/