Blog

python基于PCSC协议实现读卡器和卡片通信

2020-04-13 17:08:44 明申科技 71

简介

    PCSC协议是windows平台下的一套通用API, 所 有 函 数 的 原 型 都 winscard.h中声明,应用程序需要包含winscard.lib,所有函数的正常返回值都 SCARD_S_SUCCESS。它为读卡器/卡片和电脑提供了一个标准接口,实现不同生产商的卡片和读卡器之间的互操作性。之前工作中使用的时候是在VC++环境下之间调用的winscard提供的api,学了python之后试着用python来实现。     python由好个模块封装了PCSC的接口,比如:PySmartCard/pyscard,我是试用了PySmartCard,后面的代码也是基于PySmartCard模块编写的。


PySmartCard模块

下载地址:

PySmartCard 1.3.8


需要先pip安装这个模块,命令如下:


pip install PySmartCard


PySmartCard模块是PCSC/D8/D6/T6都支持的,我只用了PCSC。


实现代码

运行代码前需要连接上读卡器,win10下读卡器驱动貌似是默认安装的。


#encoding=utf-8

 

#导入PcscReader类

from PySmartCard.CpuCard import PcscReader

#导入time模块

import time

 

def showLog(data, issend):

      '''打印日志函数'''

      current = time.strftime('%Y_%m_%d %H:%M:%S', time.localtime())

      if issend:#发送到卡片的数据

            send = '-->'

      else:#卡片返回的数据

            send = '<--'

      print("{} {} {}".format(current, send, data))

      

def sendApdu(reader, apdu, recv_list, readerType=None):

      '''给卡片发送指令的函数'''

      #清空

      recv_list[:] = []

      #去掉多余的空格

      apdu = apdu.replace(' ','')

      showLog(apdu, True)

      respone = reader.send_apdu(apdu,readerType)

      showLog(respone, False)

      #recv_list第1个元素是返回数据

      recv_list.append(respone[:-4])

      #recv_list第2个元素是sw

      recv_list.append(respone[-4:])

 

def sendApduCommand(reader, apdu, recv_list, readerType=None):

      '''完整的发送指令函数'''

      sendApdu(reader, apdu, recv_list, readerType)

      #如果是返回的SW是6CXX或者61XX,重新发指令

      apdu = apdu.replace(' ','')

      if recv_list[-1][:2] == '61':

            apdu = '00C00000' + recv_list[-1][2:4]

            sendApdu(reader, apdu, recv_list, readerType)

      elif recv_list[-1][:2].upper() == '6C':

            apdu = apdu[:8] + recv_list[-1][2:4]

            sendApdu(reader, apdu, recv_list, readerType)

      

'''实例化PCSC读卡器'''

pcsc = PcscReader()

 

'''获取所有的读卡器列表'''

readerName = pcsc.get_pcsc_readerlist()

##print(readerName)#字符串类型的读卡器名称,按;隔开

#按;切割字符串,得到所有的读卡器名称

print('当前连接的读卡器有:')

readerNameList = readerName.split(';')

for  i  in range(len(readerNameList)-1):

      print("{} {} :{}".format('reader',i,readerNameList[i]))

 

'''连接指定的读卡器'''

print('*'*40)

#要连接的读卡器

useReaderName = "SCM Microsystems Inc. SDI010 Contactless Reader 0"

useReaderName = "SCM Microsystems Inc. SDI010 Smart Card Reader 0"

 

#得到的是字符串类型的复位信息

ATR = pcsc.connect_device(useReaderName)

if ATR:

      print("ConnectDevice Success...")

      print("ATR: ", ATR)

else:

      print("ConnectDevice Failed!")

 

'''上电'''

print('*'*40)

 #通信界面类型: 1-contact reader   2-contactless reader

readerType = 1

if 'Contactless'.lower() in useReaderName.lower():

      readerType = 2

if 0== pcsc.power_on(readerType):

      print("Device PowerOn Success...")

else:

      print("Device PowerOn Failed!")

 

'''发送APDU'''

print('*'*40)

apdu = '00A4 0400 00'

recv_list = []

sendApduCommand(pcsc,apdu, recv_list, readerType)

if recv_list[1] !="9000":

      print("Send Apdu Failed!")

 

apdu = '0084 0000 08'

recv_list = []

sendApduCommand(pcsc,apdu, recv_list, readerType)

if recv_list[1] !="9000":

      print("Send Apdu Failed!")

 

'''断开读卡器连接'''

pcsc.disconnect_device()

 

'''SM4_ECB加密计算'''

print('*'*40)

encrypt = pcsc.sm4_ecb('0123456789ABCDEFFEDCBA9876543210',

                       '0123456789ABCDEFFEDCBA9876543210',1)

print(encrypt)

 

运行结果:

明申智能卡/RFID python基于PCSC协议实现读卡器和卡片通信



首页
产品
新闻
联系