Chinaunix首页 | 论坛 | 博客
  • 博客访问: 642947
  • 博文数量: 133
  • 博客积分: 1566
  • 博客等级: 上尉
  • 技术积分: 1230
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-01 09:31
文章分类

全部博文(133)

文章存档

2019年(1)

2018年(1)

2017年(8)

2016年(9)

2015年(17)

2014年(4)

2013年(31)

2012年(25)

2011年(36)

2010年(1)

我的朋友

分类: C/C++

2013-03-05 11:14:09

一、IC卡与作业系统的整合
前面所谈的标准及各种IC卡的规格,多半只论及IC卡或读卡机。使用者要使用读卡机时,必须安装厂商提供之驱动程式(drivers),开发应用程式。
PC/SC(Personal Computer/Smart Card)支援ISO7816-4的基本指令集,界定了IC卡、读卡机及作业系统的责任与分工,各家读卡机厂商只要遵循PC/SC所定义之介面与方法开发驱动程式,即可结合到Windows或其他作业系统,应用程式只要透过单一标准介面与作业系统沟通,就可轻易操控各种读卡机读写IC卡。
Microsoft也在1997年底提供了Smart Card SDK给应用程式开发者,陆陆续续许多厂商的IC卡、读卡机产品开始宣称其产品符合PC/SC规范,PC/SC俨然成为未来时势的潮流。
应用程式与Smartcard之运作如下:
1、应用程式使用PC/SC API 传送APDU指令传给作业系统。
2、作业系统透过符合PC/SC规范之驱动程式将APDU指令传给读卡机。
3、读卡机使用T=0或T=1之通讯协议将指令传送至Smartcard传输管理器。
4、传输管理器再将APDU指令传送至Smartcard COS运作后回覆处理结果。

二、PC/SC API for Visual C++
1、#include
winscard.h是Visual C++编译时所需要的参数及基本资料结构,请记得连结时加入winscard.lib,这样才能完成您的程式,此两档在Visual C++ 的 include及library目录下可以找到,这种方式称为「隐式调用DLL」,程式好像与winscard.dll无关但实际上是透过DLL执行,. h档案内容大致如下:

#define SCARD_STATE_UNAWARE 0x00000000
#define SCARD_STATE_IGNORE 0x00000001
#define SCARD_STATE_CHANGED 0x00000002
#define SCARD_STATE_UNKNOWN 0x00000004
#define SCARD_STATE_UNAVAILABLE 0x00000008

WINSCARDDATA extern const SCARD_IO_REQUEST
g_rgSCardT0Pci,
g_rgSCardT1Pci,
g_rgSCardRawPci;

extern WINSCARDAPI LONG WINAPI
SCardEstablishContext(
IN DWORD dwScope,
IN LPCVOID pvReserved1,
IN LPCVOID pvReserved2,
OUT LPSCARDCONTEXT phContext);

其实 PC/SC 不一定要在Windows 系统执行,以下定义为Linux系统所使用之PC/SC,请比较一下差异在哪里。

typedef struct {
DWORD dwProtocol; /* SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1 */
DWORD cbPciLength; /* Length of this structure - not used */
} SCARD_IO_REQUEST;

long SCardEstablishContext(unsigned long dwScope,const void *pvReserved1, const void *pvReserved2, long *phContext);

以下说明一些重要函式之功能,细节部分请参考,附件二、PC/SC API Reference Document。

2、ScardEstablishContext
SCardEstablishContext 直觉的解释就是建立PC/SC在作业系统下的资源,所有PC/SC应用程式开始时一定要呼叫此函式建立资源后才能开始运作,范例如下。

SCARDCONTEXT hContext;
LONG rv;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

3、ScardListReaders
SCardListReaders 直觉的解释就是列出此台机器可用之Smartcard 读卡机,比较特别的是第一次呼叫时并不知道机器有几台可用之读卡机所以mszReaders先代入NULL,取得实际数量后再呼叫一次就可列出读卡机名称,此技巧运用在很多API 呼叫中,第一次看到觉得怪怪,仔细想想此种呼叫方式真聪明。

LPTSTR mszReaders;
DWORD dwReaders;
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
mszReaders = (LPTSTR)malloc(sizeof(char)*dwReaders);
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);

4、ScardConnect
SCardConnect 直觉的解释就是建立Smartcard之连线,参数就是代入SCardListReaders 所列出之读卡机名称;当连线完成后Smartcard会被重置,传回ATR讯息。

SCARDHANDLE hCard;
DWORD dwActiveProtocol;
rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);

5、ScardBeginTransaction
当读卡机以分享方式开启时,SCardBeginTransaction 就是宣告尔后将执行一连串的APDU指令以确保中间不被插断,当结束所有APDU指令后需呼叫ScardEndTransaction让其他连线继续运作;当读卡机以独占方式开启时,可以不必执行此函式,直接执行SCardTransmit即可。

rv = SCardBeginTransaction(hCard);

6、ScardTransmit
SCardTransmit是在呼叫SCardConnect函式后,传送APDU 指令到Smartcard的函式,可说是整个Smartcard程式设计的核心,在此特别说明下列程式。
DWORD dwSendLength, dwRecvLength;
SCARD_IO_REQUEST pioRecvPci;
/*必须使用BYTE传送及接收资料,如果您输入的指令是CHAR记得转换为BYTE ,很特别的是此函式呼叫时就已经定义好接收资料*/
BYTE pbRecvBuffer[10];
/*此行即为APDU Command,特别解释一下,这行指令是选取Master File。
Command CLA INS P1 P2 Lc Data Le
Select C0 A4 00 00 02 3F00
*/
BYTE pbSendBuffer[] = { 0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };

dwSendLength = sizeof(pbSendBuffer);
dwRecvLength = sizeof(pbRecvBuffer);
rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength,
&pioRecvPci, pbRecvBuffer, &dwRecvLength);

7、SCardEndTransaction
SCardEndTransaction 是结束之前SCardBeginTransaction 之宣告;必须与SCardBeginTransaction配对使用。

rv = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);

8、ScardDisconnect
SCardDisconnect 是结束之前SCardConnect所建立的连线,呼叫此函式后就无法在传送APDU指令了。

rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);

9、ScardReleaseContext
SCardReleaseContext 直觉的解释就是释放SCardEstablishContext 在作业系统下所建立的资源,所有PC/SC应用程式结束时一定要呼叫此函式归还资源。

rv = SCardReleaseContext(hContext);

10、其他PC/SC API
PC/SC API函式不只这些,某些应用场合可能会使用到,请参考附件二、PC/SC API Reference Document。

阅读(3357) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~