因为PC/SC是Windows的体系,以系统API的层面服务应用。所以一直以来智能卡相关的读卡器和工具都集中在Windows上,而在 unix体系下则一直水土不服。值得庆幸的是随着开源组织M.U.S.C.L.E (Movment for the Use of Smart in Linux Environment)的积极努力下,pcsclite作为Xnix下的PC/SC设备框架和应用接口已经成为了事实上的标准,Mac的Lion系统更 是已经在发行版里面集成了此服务。下面以ubuntu 12.0.4 发行版为例子。
#首先安装pcsc的守护进程pcscd和工具
sudo apt-get -y install libusb-dev
sudo apt-get -y install pcscd
#然后安装支持pcsc的读卡器驱动(例子为内置的ACR ACS38U,其它读卡器也可以到网站下载安装)
sudo apt-get -y install libacr38u
#连接读卡器,插卡后运行扫描工具验证安装结果
pcsc_scan
结果如下:
PC/SC device scanner
V 1.4.18 (c) 2001-2011, Ludovic Rousseau
Compiled with PC/SC lite version: 1.7.4
Using reader plug'n play mechanism
Scanning present readers...
0: ACS ACR38U 00 00
Thu Sep 20 12:55:08 2012
Reader 0: ACS ACR38U 00 00
ATR: 3B 1D 94 42 72 6F 61 64 54 68 69 6E 6B 69 00 00
+ TS = 3B --> Direct Convention
+ T0 = 1D, Y(1): 0001, K: 13 (historical bytes)
+ Historical bytes: 42 72 6F 61 64 54 68 69 6E 6B 69 00 00
Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
NONE
Your card is not present in the database.
You can get the latest version of the database from
or use: wget http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt --output-document=/home/caesarzou/.smartcard_list.txt
If your ATR is still not in the latest version then please send a mail
to containing:
#到此为止,PC/SC驱动已经打通,现在我们试试发个APDU
sudo apt-get -y install pcsc-tools
gscriptor
这是一个图形界面的工具,在Script框里面输入:
00A4040000
点Run按钮,可以看到连接提示,然后就是结果:
Beginning script execution...
Sending: 00 A4 04 00 00
Received: 6C 12
Wrong length Le: should be 0x12
Script was executed without error...
#恭喜你,卡片访问成功,现在你一定心痒难耐,想创建你自己的应用了吧?
#安装开发库
sudo apt-get install libpcsclite-dev
#安装eclipse的cdt作为开发环境
sudo apt-get -y install g++
sudo apt-get -y install eclipse eclipse-cdt
#打开eclipse,新建一个C工程,在c文件中加入
#include
#链接到pcsclite库:在C/C++ build / GCC Linker / Libraries 增加 pcsclite
#现在你会幸福的发现,winscard.h里面提供的类型定义和接口和windows是一致的,我们从windows中拷贝一段代码过来:
- #include
- #include
-
- int
main(void) { -
SCARDCONTEXT m_hContext; -
SCARDHANDLE m_hCard; -
SCARD_IO_REQUEST io; -
char pmszReaders[100]; -
BYTE CAPDU[] = {0x00,0xA4,0x04,0x00,0x00}; -
BYTE RAPDU[256+2]; -
DWORD cch = 100; -
DWORD i = 0; -
-
//Insert -
if(SCARD_S_SUCCESS != SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &m_hContext)) -
{ -
printf("Context error"); -
return -1; -
} -
-
//List Reader -
if(SCARD_S_SUCCESS != SCardListReaders(m_hContext, NULL, pmszReaders, &cch)) -
{ -
printf("List Reader error"); -
return -2; -
} -
-
printf("List Readers\n"); -
while(i -
{ -
printf("%s\n",pmszReaders+i); -
i += strlen(pmszReaders); -
i ++; -
} -
-
//Connect first Reader -
io.cbPciLength = sizeof(SCARD_IO_REQUEST); -
-
if(SCARD_S_SUCCESS != SCardConnect(m_hContext, pmszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, &m_hCard, &io.dwProtocol)) -
{ -
printf("Connect Card error"); -
return -3; -
} -
-
//Transmit APDU -
cch = 256+2; -
if(SCARD_S_SUCCESS != SCardTransmit(m_hCard, &io, CAPDU, 5, NULL, RAPDU, &cch)) -
{ -
printf("Transmit APDU error"); -
return -4; -
} -
//echo -
printf("Transmit APDU\n"); -
printf("CAPDU: "); -
for(i=0;i<5;i++) -
{ -
sprintf(pmszReaders,"X",CAPDU[i]); -
printf("%s",pmszReaders); -
} -
printf("\n"); -
printf("RAPDU: "); -
for(i=0;i -
{ -
sprintf(pmszReaders,"X",RAPDU[i]); -
printf("%s",pmszReaders); -
} -
printf("\n"); -
-
//DisConnect -
SCardDisconnect(m_hCard, SCARD_EJECT_CARD); -
-
//Eject -
SCardReleaseContext(m_hContext); -
//puts("!!!Hello World!!!"); -
return 0; - }
List Readers
ACS ACR38U 00 00
Transmit APDU
CAPDU: 00A4040000
RAPDU: 6C12
大功告成!下一个攻略我会讲一下在ubuntu上基于JavaCard环境和工具的配置,敬请期待。
注:
sudo vim /usr/include/PCSC/winscard.h
将#include 修改为#include ,保存退出
sudo vim /usr/include/PCSC/pcsclite.h
将#include 修改为#include ,保存推出
原文:http://blog.csdn.net/caesarzou/article/details/7999624