#! /usr/bin/env python """ Smart Card Reader / Writer """ from smartcard.CardType import AnyCardType from smartcard.CardRequest import CardRequest from smartcard.util import toHexString from smartcard.ATR import ATR from Crypto.Cipher import DES3 as des3 import random as rnd import time as tm import matplotlib.pyplot as plt import math import logging # 通过下面的方式进行简单配置输出方式与日志级别 logging.basicConfig(filename='logger.log', level=logging.INFO) # 初始化读卡器 def init(): print('初始化读卡器') card_type = AnyCardType() card_request = CardRequest(timeout=1, cardType=card_type) card_service = card_request.waitforcard() card_service.connection.connect() # atr = ATR(card_service.connection.getATR()) return card_service def result_print(result_out_str): print(result_out_str) logging.info(result_out_str) def trace_command(apdu): print('sending ', toHexString(apdu)) logging.info('sending: '+ toHexString(apdu)) def trace_response(response, sw1, sw2): if response is None: response = [] print( 'serial no.: ', toHexString(response), ' status words: ', "%x %x" % (sw1, sw2) ) logging.info( 'serial no.: '+ toHexString(response)+ ' status words: '+ "%x %x" % (sw1, sw2)) def bytes2int(data_bytes): data_number = len(data_bytes) data_int = 0 for i in range(0, data_number): data_int = data_int + data_bytes[data_number-i-1]*math.pow(2, i*8) return int(data_int) def int2bytes(data_int): return bytes([data_int]) def bytes2int_list(data_bytes): data_number = len(data_bytes) data_int_list = list(range(data_number)) for i in range(0, data_number): data_int_list[i] = int(str(data_bytes[i])) return data_int_list def hexstr2bytes(hex_str): hex_int_list = hexstr2int_list(hex_str) hex_bytes = int_list2bytes(hex_int_list) return hex_bytes def bytes2hexstr(data_bytes): data_number = len(data_bytes) data_hex_str = '' for i in range(0, data_number): data_int = int(str(data_bytes[i])) data_hex_str += "{:02X} ".format(data_int) return data_hex_str def hexstr2int_list(data_str): data_str = data_str.replace('0x', '') data_str = data_str.replace(' ', '') data_str = data_str.replace('\r', '') data_str = data_str.replace('\n', '') data_str = data_str.replace(',', '') data_number_int = int(len(data_str)/2) data_bytes_list = list(range(data_number_int)) data_int_list = list(range(data_number_int)) for i in range(0, data_number_int): data_bytes_list[i] = bytes.fromhex(data_str[i*2:i*2+2]) data_int_list[i] = int.from_bytes(data_bytes_list[i], 'big') return data_int_list def int_list2bytes(data_int_list): data_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), data_int_list)) return data_bytes #发送指令 def sendCommand(card_service,command): trace_command(command) res, s1, s2 = card_service.connection.transmit(command) trace_response(res, s1, s2) return res,s1,s2 # 权限验证 def COS_Access(card_service,KEYA_str, KEYB_str): print('开始ACCESS验证') rf_command_bytes = [ 0xA2, 0xA4, 0x00, 0x0C, 0x02, 0xAC, 0x01] data_byres,s1,s2 = sendCommand(card_service,rf_command_bytes) if s1==99 and s2 == 192: print('解锁标签') tm.sleep(15) rf_command_bytes = [ 0xA2, 0xA4, 0x00, 0x0C, 0x02, 0xAC, 0x01] data_byres,s1,s2 = sendCommand(card_service,rf_command_bytes) return rf_command_bytes = [0xA2, 0xB0, 0x00, 0x10, 0x10] data_bytes,s1,s2 = sendCommand(card_service,rf_command_bytes) trnd_bytes = data_bytes[0:8] mid_bytes = data_bytes[8:17] # 计算KEYA* KEYB* random_int_list = bytes2int_list(trnd_bytes) mid_int_list = bytes2int_list(mid_bytes) keya_int_list = hexstr2int_list(KEYA_str) keyb_int_list = hexstr2int_list(KEYB_str) des3_key_list = [0 for i in range(16)] for i in range(0,8): des3_key_list[i] = random_int_list[i] ^ keya_int_list[i] des3_key_list[i+8] = mid_int_list[i] ^ keyb_int_list[i] des3_key_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), des3_key_list)) Des3_Cipher = des3.new(des3_key_bytes, des3.MODE_ECB) # 加密随机数 random_key_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), random_int_list)) trnd_encrpyt_bytes = Des3_Cipher.encrypt(random_key_bytes) # trnd_bytes= rnd.randbytes(8) trnd_bytes = [0xA2,0xD6,0x00,0x10,0x10,0x00,0x10,0x10] command_bytes = [0xA2,0xD6,0x00,0x10,0x10] command_bytes.extend(trnd_encrpyt_bytes) command_bytes.extend(trnd_bytes) res,s1,s2 = sendCommand(card_service,command_bytes) if s1 == 144 and s2 == 0: res,s1,s2 = sendCommand(card_service,[0xA2,0xB0,0x00,0x10,0x10]) # sendCommand(res) # trnd_encrpyt_bytes = Des3_Cipher.encrypt(trnd_bytes) return Des3_Cipher # 读读取数据 def COS_Read_Data(card_service,Des3_Cipher, address_int, length_int, package_size): result_print("COS读取数据") result = False # 选中PL DATA rf_command_bytes = [0xA2,0xA4,0x00,0x0C,0x02,0xDA,0x01] data_bytes,s1,s2 = sendCommand(rf_command_bytes) # 读数据 data_bytes = ISO14443_4A_ReadBinary(0xA2, address_int, length_int, package_size) data_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), data_bytes)) data_bytes = Des3_Cipher.decrypt(data_bytes) data_str = bytes2hexstr(data_bytes) result = True result_print("成功", result) result_print(data_str, result) return result, data_bytes # 读取温度 def COS_Read_Tempture(card_service,Des3_Cipher): result_print("COS读取温度") result = False tempture_int = 0 # 选中PL DATA command_bytes = [0xA2,0xA4,0x00,0x0C,0x02,0xDA,0x01] data_bytes,s1,s2 = sendCommand(card_service,command_bytes) # 读取数据 data_bytes = ISO14443_4A_ReadBinary(card_service,0xA2, 0, 80, 60) data_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), data_bytes)) data_bytes = Des3_Cipher.decrypt(data_bytes) # 解析数据 data_bias = 12 CID_bytes = data_bytes[data_bias+0: data_bias+2] TID_bytes = data_bytes[data_bias+2: data_bias+8] GTIN_bytes = data_bytes[data_bias+8: data_bias+18] VID_bytes = data_bytes[data_bias+18:data_bias+26] MID_bytes = data_bytes[data_bias+26:data_bias+34] MAC_bytes = data_bytes[data_bias+34:data_bias+42] TRNG_bytes = data_bytes[data_bias+42:data_bias+50] PAGE_bytes = data_bytes[data_bias+50:data_bias+51] RNUM_bytes = data_bytes[data_bias+51:data_bias+55] Cal_Data = [[0 for i in range(2)] for j in range(3)] Cal_Data[0][0] = (data_bytes[data_bias+55]*16 + (data_bytes[data_bias+56]>>4))/10 Cal_Data[0][1] = (data_bytes[data_bias+56]&0x0F)*256 + data_bytes[data_bias+57] Cal_Data[1][0] = (data_bytes[data_bias+58]*16 + (data_bytes[data_bias+59]>>4))/10 Cal_Data[1][1] = (data_bytes[data_bias+59]&0x0F)*256 + data_bytes[data_bias+60] Cal_Data[2][0] = (data_bytes[data_bias+61]*16 + (data_bytes[data_bias+62]>>4))/10 Cal_Data[2][1] = (data_bytes[data_bias+62]&0x0F)*256 + data_bytes[data_bias+63] info_json = { "CID":bytes2hexstr(CID_bytes), "TID":bytes2hexstr(TID_bytes), "GTIN":bytes2hexstr(GTIN_bytes), "VID":bytes2hexstr(VID_bytes), "MID":bytes2hexstr(MID_bytes), "MAC":bytes2hexstr(MAC_bytes), "TRNG":bytes2hexstr(TRNG_bytes), "PAGE":bytes2hexstr(PAGE_bytes), "RUNM":bytes2hexstr(RNUM_bytes), "CAL1":{ "TEMP":str(Cal_Data[0][0]), "ADC":str(Cal_Data[0][1]) }, "CAL2":{ "TEMP":str(Cal_Data[1][0]), "ADC":str(Cal_Data[1][1]) }, "CAL3":{ "TEMP":str(Cal_Data[2][0]), "ADC":str(Cal_Data[2][1]) } } command_bytes = [0xA2,0xB0,0x00,0x4E,0x08] data_bytes,s1,s2 = sendCommand(card_service,command_bytes) data_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), data_bytes)) data_bytes = Des3_Cipher.decrypt(data_bytes) tempture_int = int(str(data_bytes[0]))*256 + int(str(data_bytes[1])) adc_data_int = tempture_int >> 5 if(adc_data_int>4))/10 Cal_Data[0][1] = (data_bytes[data_bias+56]&0x0F)*256 + data_bytes[data_bias+57] Cal_Data[1][0] = (data_bytes[data_bias+58]*16 + (data_bytes[data_bias+59]>>4))/10 Cal_Data[1][1] = (data_bytes[data_bias+59]&0x0F)*256 + data_bytes[data_bias+60] Cal_Data[2][0] = (data_bytes[data_bias+61]*16 + (data_bytes[data_bias+62]>>4))/10 Cal_Data[2][1] = (data_bytes[data_bias+62]&0x0F)*256 + data_bytes[data_bias+63] info_str = "CID: " + bytes2hexstr(CID_bytes) + "\n" + \ "TID: " + bytes2hexstr(TID_bytes) + "\n" + \ "GTIN: " + bytes2hexstr(GTIN_bytes) + "\n" + \ "VID: " + bytes2hexstr(VID_bytes) + "\n" + \ "MID: " + bytes2hexstr(MID_bytes) + "\n" + \ "MAC: " + bytes2hexstr(MAC_bytes) + "\n" + \ "TRNG: " + bytes2hexstr(TRNG_bytes) + "\n" + \ "PAGE: " + bytes2hexstr(PAGE_bytes) + "\n" + \ "RNUM: " + bytes2hexstr(RNUM_bytes) + "\n" + \ "CAL1: " + str(Cal_Data[0][0]) + " " + str(Cal_Data[0][1]) + "\n" + \ "CAL2: " + str(Cal_Data[1][0]) + " " + str(Cal_Data[1][1]) + "\n" + \ "CAL3: " + str(Cal_Data[2][0]) + " " + str(Cal_Data[2][1]) info_json = { "CID":bytes2hexstr(CID_bytes), "TID":bytes2hexstr(TID_bytes), "GTIN":bytes2hexstr(GTIN_bytes), "VID":bytes2hexstr(VID_bytes), "MID":bytes2hexstr(MID_bytes), "MAC":bytes2hexstr(MAC_bytes), "TRNG":bytes2hexstr(TRNG_bytes), "PAGE":bytes2hexstr(PAGE_bytes), "RUNM":bytes2hexstr(RNUM_bytes), "CAL1":{ "TEMP":str(Cal_Data[0][0]), "ADC":str(Cal_Data[0][1]) }, "CAL2":{ "TEMP":str(Cal_Data[1][0]), "ADC":str(Cal_Data[1][1]) }, "CAL3":{ "TEMP":str(Cal_Data[2][0]), "ADC":str(Cal_Data[2][1]) } } result_print(info_json) record_number_int = bytes2int(RNUM_bytes) record_data_size_int = int(record_number_int*11/8) if(record_number_int*11%8): record_data_size_int += 1 record_data_size_mod_int = record_data_size_int%8 if(record_data_size_mod_int): record_data_size_int = record_data_size_int + (8-record_data_size_mod_int) # 读取数据 NDEF_MAX_INT = 4032 start_address_int = 78 if (start_address_int+record_data_size_int)>NDEF_MAX_INT: record_data_size_int = record_data_size_int - 8 record_number_int = int(record_data_size_int*8/11) data_bytes = ISO14443_4A_ReadBinary(card_service,0xA2, 78, record_data_size_int, DATA_SIZE) data_bytes = b''.join(map(lambda d:int.to_bytes(d, 1, 'little'), data_bytes)) data_bytes = Des3_Cipher.decrypt(data_bytes) # 解析adc tempture_data = [0 for i in range(record_number_int)] repeat_cnt = int(record_number_int/8) count_residue = record_number_int%8 if count_residue>0: repeat_cnt += 1 decode_count = 0 for i in range(0, repeat_cnt): for j in range(0, 8): if decode_count>=record_number_int: break else: decode_count += 1 if j==0: adc_data_int = data_bytes[i*11]*256+data_bytes[i*11+1] adc_data_int = (adc_data_int&0x0000FFE0)>>5 elif j==1: adc_data_int = data_bytes[i*11+1]*256+data_bytes[i*11+2] adc_data_int = (adc_data_int&0x00001FFC)>>2 elif j==2: adc_data_int = data_bytes[i*11+2]*65536+data_bytes[i*11+3]*256+data_bytes[i*11+4] adc_data_int = (adc_data_int&0x0003FF80)>>7 elif j==3: adc_data_int = data_bytes[i*11+4]*256+data_bytes[i*11+5] adc_data_int = (adc_data_int&0x00007FF0)>>4 elif j==4: adc_data_int = data_bytes[i*11+5]*256+data_bytes[i*11+6] adc_data_int = (adc_data_int&0x00000FFE)>>1 elif j==5: adc_data_int = data_bytes[i*11+6]*65536+data_bytes[i*11+7]*256+data_bytes[i*11+8] adc_data_int = (adc_data_int&0x0001FFC0)>>6 elif j==6: adc_data_int = data_bytes[i*11+8]*256+data_bytes[i*11+9] adc_data_int = (adc_data_int&0x000003FF8)>>3 elif j==7: adc_data_int = data_bytes[i*11+9]*256+data_bytes[i*11+10] adc_data_int = (adc_data_int&0x000007FF)>>0 adc_data_int = int(adc_data_int) if TEMPTURE_SHOW==True: if(adc_data_int