ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:18.77KB ,
资源ID:6787822      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6787822.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(VC中PCSC操作读卡器.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

VC中PCSC操作读卡器.docx

1、VC中PCSC操作读卡器VC中PC/SC智能卡接口的编程来源:网络作者:蒋遂平发布时间:2010-12-10 10:53:20字体:大 中 小关键字:智能卡接口读卡器摘要:终端应用程序需要通过读卡器来访问智能卡,在一个系统中,通常存在多家厂商提供的读卡器,因此需要一个统一的读卡器设备驱动接口。 1 引言 完整的智能卡应用系统由后台服务程序、主机或终端应用程序和智能卡等组成,其中,后台服务程序提供了支持智能卡的服务。例如,在一个电子付款系统中,后台服务程序可以提供到信用卡和帐户信息的访问;主机或终端应用程序一般存在于台式机或者终端、电子付款终端、手机或者一个安全子系统中,终端应用程序要处理用户、

2、智能卡和后台服务程序之间的通讯;智能卡则存储用户的一些信息。 终端应用程序需要通过读卡器来访问智能卡,在一个系统中,通常存在多家厂商提供的读卡器,因此需要一个统一的读卡器设备驱动接口。 随着智能卡的广泛应用,为解决计算机与各种读卡器之间的互操作性问题,人们提出了PC/SC(Personal Computer/Smart Card)规范,PC/SC规范作为读卡器和卡与计算机之间有一个标准接口,实现不同生产商的卡和读卡器之间的互操作性,其独立于设备的 API使得应用程序开发人员不必考虑当前实现形式和将来实现形式之间的差异,并避免了由于基本硬件改变而引起的应用程序变更,从而降低了软件开发成本。 Mi

3、crosoft在其Platform SDK中实现了PC/SC,作为连接智能卡读卡器与计算机的一个标准模型,提供了独立于设备的 API,并与Windows平台集成。因此,我们可以用PC/SC接口来访问智能卡。 2 PC/SC概述 PC/SC接口包含30多个以Scard为前缀的函数,所有函数的原型都在winscard.h中声明,应用程序需要包含winscard.lib,所有函数的正常返回值都是SCARD_S_SUCCESS。在这30多个函数中,常用的函数只有几个,与智能卡的访问流程(图2)对应,下面将详细介绍这些常用函数。 3 PC/SC的使用 3.1建立资源管理器的上下文 函数ScardEsta

4、blishContext()用于建立将在其中进行设备数据库操作的资源管理器上下文(范围)。 函数原型:LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); 各个参数的含义:(1)dwScope:输入类型;表示资源管理器上下文范围,取值为:SCARD_SCOPE_USER(在用户域中完成设备数据库操作)、SCARD_SCOPE_SYSTEM(在系统域中完成设备数据库操作)。要求应用程序具有相应的操作权限。(2)pvReserved

5、1:输入类型;保留,必须为NULL。(3)pvReserved2:输入类型;保留,必须为NULL。(4)phContext:输出类型;建立的资源管理器上下文的句柄。 下面是建立资源管理器上下文的代码: SCARDCONTEXT hSC; LONG lReturn; lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC); if ( lReturn!=SCARD_S_SUCCESS ) printf(Failed SCardEstablishContextn); 3.2 获得系统中安装的读卡器列表 函数ScardLi

6、stReaders()可以列出系统中安装的读卡器的名字。 函数原型:LONG SCardListReaders(SCARDCONTEXT hContext, LPCTSTR mszGroups, LPTSTR mszReaders, LPDWORD pcchReaders); 各个参数的含义:(1)hContext:输入类型;ScardEstablishContext()建立的资源管理器上下文的句柄,不能为NULL。(2)mszGroups:输入类型;读卡器组名,为NULL时,表示列出所有读卡器。(3)mszReaders:输出类型;系统中安装的读卡器的名字,各个名字之间用0分隔,最后一个名字

7、后面为两个连续的0。(4)pcchReaders:输入输出类型;mszReaders的长度。 系统中可能安装多个读卡器,因此,需要保存各个读卡器的名字,以便以后与需要的读卡器建立连接。 下面是获得系统中安装的读卡器列表的代码: char mszReaders1024; LPTSTR pReader, pReaderName2; DWORD dwLen=sizeof(mzsReaders); int nReaders=0; lReturn = SCardListReaders(hSC, NULL, (LPTSTR)mszReaders, &dwLen); if ( lReturn=SCARD_S

8、_SUCCESS ) pReader = (LPTSTR)pmszReaders; while (*pReader !=0 ) if ( nReaders0字节数据时,pbSendBuffer 前4字节分别为T=0的CLA、INS、P1、P2,第5字节是n,随后是n字节的数据;cbSendLength值为n+5(4字节头+1字节Lc+n字节数据)。PbRecvBuffer将接收SW1、SW2状态码;pcbRecvLength值在调用时至少为2,返回后为2。 BYTE recvBuffer260; int sendSize, recvSize; BTYE sw1, sw2; BYTE selec

9、t_mf=0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00; sendSize=7; recvSize=sizeof(recvBuffer); lReturn = SCardTransmit(hCardHandle0, SCARD_PCI_T0, select_mf, sendSize, NULL, recvBuffer, &recvSize); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardTransmitn); exit(1); /返回的数据,recvSize=2 sw1=recvBufferrec

10、vSize-2; sw2=recvBufferrecvSize-1; (b)从智能卡接收数据:为从智能卡接收n0字节数据,pbSendBuffer 前4字节分别为T=0的CLA、INS、P1、P2,第5字节是n(即Le),如果从智能卡接收256字节,则第5字节为0;cbSendLength值为5(4字节头+1字节Le)。PbRecvBuffer将接收智能卡返回的n字节,随后是SW1、SW2状态码;pcbRecvLength的值在调用时至少为 n+2,返回后为n+2。 BYTE get_challenge=0x00, 0x84, 0x00, 0x00, 0x08; sendSize=5; rec

11、vSize=sizeof(recvBuffer); lReturn = SCardTransmit(hCardHandle0, SCARD_PCI_T0, get_challenge, sendSize, NULL, recvBuffer, &recvSize); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardTransmitn); exit(1); /返回的数据, recvSize=10 sw1=recvBufferrecvSize-2; sw2=recvBufferrecvSize-1; /data=recvBuffer0-rec

12、vBuffer7 (c)向智能卡发送没有数据交换的命令:应用程序既不向智能卡发送数据,也不从智能卡接收数据,pbSendBuffer 前4字节分别为T=0的CLA、INS、P1、P2,不发送P3;cbSendLength 值必须为4。PbRecvBuffer从智能卡接收SW1、SW2状态码;pcbRecvLength值在调用时至少为2,返回后为2。 BYTE set_flag=0x80, 0xFE, 0x00, 0x00; sendSize=4; recvSize=sizeof(recvBuffer); lReturn = SCardTransmit(hCardHandle0, SCARD_P

13、CI_T0, set_flag, sendSize, NULL, recvBuffer, &recvSize); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardTransmitn); exit(1); /返回的数据,recvSize=2 sw1=recvBufferrecvSize-2; sw2=recvBufferrecvSize-1; (d)向智能卡发送具有双向数据交换的命令:T=0协议中,应用程序不能同时向智能卡发送数据,并从智能卡接收数据,即发送到智能卡的指令中,不能同时有Lc和Le。这只能分两步实现:向智能卡发送数据,接收智

14、能卡返回的状态码,其中,SW2是智能卡将要返回的数据字节数目;从智能卡接收数据(指令为0x00、0xC0、0x00、0x00、Le)。 BYTE get_response=0x00, 0xc0, 0x00, 0x00, 0x00; BYTE internal_auth=0x00, 0x88, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08; sendSize=13; recvSize=sizeof(recvBuffer); lReturn = SCardTransmit(hCardHandle0, SCARD_P

15、CI_T0, internal_auth, sendSize, NULL, recvBuffer, &recvSize); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardTransmitn); exit(1); /返回的数据,recvSize=2 sw1=recvBufferrecvSize-2; sw2=recvBufferrecvSize-1; if ( sw1!=0x61 ) printf(Failed Commandn); exit(1); get_response4=sw2; sendSize=5; recvSize=siz

16、eof(recvBuffer); lReturn = SCardTransmit(hCardHandle0, SCARD_PCI_T0, get_response, sendSize, NULL, recvBuffer, &recvSize); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardTransmitn); exit(1); /返回的数据,recvSize=10 sw1=recvBufferrecvSize-2; sw2=recvBufferrecvSize-1; /data=recvBuffer0-recvBuffer7 3.

17、5 断开与读卡器(智能卡)的连接 在与智能卡的数据交换完成后,可以使用函数ScardDisconnect()终止应用与智能卡之间的连接。 函数原型:LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition); 各个参数的含义:(1)hCard:输入类型;与智能卡连接的句柄。(2)dwDisposition:输入类型;断开连接时,对智能卡的操作,SCARD_LEAVE_CARD(不做任何操作)、SCARD_RESET_CARD(复位智能卡)、SCARD_UNPOWER_CARD(给智能卡掉电)、SCARD_EJECT_CARD(弹出智

18、能卡)。 下面是断开与智能卡连接的代码: lReturn = SCardDisconnect(hCardHandle0, SCARD_LEAVE_CARD); if ( lReturn != SCARD_S_SUCCESS ) printf(Failed SCardDisconnectn); exit(1); 3.6 释放资源管理上下文 在应用程序终止前时,应该调用函数ScardReleaseContext()释放资源管理器的上下文。 函数原型:LONG SCardReleaseContext(SCARDCONTEXT hContext); 各个参数含义:(1)hContext:输入类型;Sc

19、ardEstablishContext()建立的资源管理器上下文的句柄,不能为NULL。 下面是释放资源管理上下文的代码: lReturn = SCardReleaseContext(hSC); if ( lReturn!=SCARD_S_SUCCESS ) printf(Failed SCardReleaseContextn); 4 小结 以上介绍的通过PC/SC来操作智能卡的流程,可以封装在一个类中。例如,我们可以设计一个类: class CSmartReader private: SCARDCONTEXT hSC; LONG lReturn; char mszReaders1024; L

20、PTSTR pReader, pReaderName2; DWORD dwLen; int nReaders, nCurrentReader; SCARDHANDLE hCardHandle2; DWORD dwAP; public: CSmartReader(); /建立上下文、取读卡器列表 CSmartReader(); /释放上下文 void SetCurrentReader(int currentReader); int GetReaders(); /获得读卡器数目 int ConnectReader(); /与当前读卡器建立连接 int DisConnectReader(); /与当前读卡器断开连接 int SendCommand(BYTE command, int commandLength, BYTE result, int *resultLength); /向读卡器发送命令,并接收返回的数据。返回值为sw ; 这样,我们就可以方便地使用PC/SC接口了。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1