def case_3e(self, full): # send data to the card # > 80 12 01 80 00 00 07 00 01 02 03 04 05 06 # < [] 90 0 CASE_3 = toBytes("80 12 01 80 00 00 00") print "Case 3 extended" print if toHexString(self.ATR) != "3B D6 18 00 81 B1 80 7D 1F 03 80 51 00 61 10 30 8F": print_error("Wrong card inserted!") print "Got ATR:", toHexString(self.ATR) return end = 65535 step = 100 if full: start = 1 else: start = end expected = ([], 0x90, 0x00) for length in range(start, end + 1, step): print self.BOL, "length:", length APDU = list(CASE_3) APDU[5] = (length & 0xFF00) >> 8 APDU[6] = length & 0x00FF APDU += [i for i in range(0, length)] self.transmitAndCompare(APDU, expected)
def case_2e(self, full): # gets (1 to 256) data from the card # > 80 00 04 2A 00 00 07 # < 2A 2A 2A 2A 2A 2A 2A 90 0 magic_value = 42 CASE_2 = toBytes("80 00 04 00 00 00 00") CASE_2[3] = magic_value print "Case 2 extended" print # ATRs of the Athena test cards Athena_ATRs = ["3B D6 18 00 80 B1 80 6D 1F 03 80 51 00 61 10 30 9E", "3F 96 18 80 01 80 51 00 61 10 30 9F"] if toHexString(self.ATR) not in Athena_ATRs: print_error("Wrong card inserted!") print "Got ATR:", toHexString(self.ATR) return step = 100 end = 65535 if full: start = 1 else: start = end for length in range(start, end + 1, step): print self.BOL, "length:", length APDU = list(CASE_2) APDU[5] = (length & 0xFF00) >> 8 APDU[6] = length & 0x00FF expected = ([magic_value] * length, 0x90, 0x00) self.transmitAndCompare(APDU, expected)
def time_extension(self, extension): # time extension TIME = toBytes("80 38 00 00") TIME[3] = extension expected = ([], 0x90, 0x00) self.transmitAndCompare(TIME, expected)
def auth(self, key = 16*'00', key_num=0x00): """Authentification process Do the authentification 1st step, get the tag nonce and do byte shifting """ sys.stdout.write("Authenticating... ") cmd = toBytes ("FF 00 00 00 0A D4 40 01 90 0A 00 00 01") cmd.append(key_num) cmd.append(0x00) data, sw1, sw2 = self.session.sendCommandAPDU( cmd ) if sw1!=0x61 or sw2!=0x0F: sys.stdout.write("[Fail]\n") return False data, sw1, sw2 = self.getAnswer (sw2) dfdata, dfsw1, dfsw2 = errors.evaluateResponse (data) if (dfsw1 != 0x91): sys.stdout.write('[Fail]\n') return False n_t = crc.mergeList(dfdata) n2_t = unhexlify( n_t ) response, nr = challenge.generateResponse(n2_t, key) cmd = "FF 00 00 00 19 D4 40 01 90 AF 00 00 10" cmd += hexlify(response) cmd += "00" data, sw1, sw2 = self.session.sendCommandAPDU( toBytes(cmd) ) if sw1!=0x61 or sw2!=0x0F: sys.stdout.write("[Fail]\n") return False data, sw1, sw2 = self.getAnswer (sw2) dfdata, dfsw1, dfsw2 = errors.evaluateResponse (data) if not errors.isOpOk (dfsw1, dfsw2): sys.stdout.write('[Fail]\n') return False n2_r = crc.mergeList(dfdata) if challenge.verifyResponse(n2_r, nr, key): sys.stdout.write("[Done]\n") else: sys.stdout.write("[Fail]\n")
def exchange(self, apdu, timeout=TIMEOUT): if self.debug: print("SC => %s" % hexstr(apdu)) response, sw1, sw2 = self.device.transmit(toBytes(hexlify(apdu))) sw = (sw1 << 8) | sw2 if self.debug: print("SC <= %s%.2x" % (hexstr(response).replace(" ", ""), sw)) if sw != 0x9000 and (sw & 0xFF00) != 0x6100 and (sw & 0xFF00) != 0x6C00: raise CommException("Invalid status %04x" % sw, sw, bytearray(response)) return bytearray(response)
def case_1(self, full): # no data exchanged # > 80 30 00 00 00 # < [] 90 0 CASE_1 = toBytes("80 30 00 00 00") print "Case 1" expected = ([], 0x90, 0x00) self.transmitAndCompare(CASE_1, expected)
def OnTransmit(self, event): if hasattr(self.selectedcard, 'connection'): apdu = self.commandtextctrl.GetValue() if type(u'') == type(apdu): apdu = apdu.encode('utf8') data, sw1, sw2 = self.selectedcard.connection.transmit(toBytes(apdu)) self.SW1textctrl.SetValue("%x" % sw1) self.SW2textctrl.SetValue("%x" % sw2) self.responsetextctrl.SetValue(toHexString(data + [sw1, sw2])) event.Skip()
def test_ATR_get(self): atr = "3B F2 95 12 34 01 36 06" a = ATR(toBytes(atr)) self.assertEqual(a.getTA1(), 0x95) self.assertEqual(a.getTB1(), 0x12) self.assertEqual(a.getTC1(), 0x34) self.assertEqual(a.getTD1(), 0x01) self.assertEqual(a.getHistoricalBytes(), [0x36, 0x06]) self.assertFalse(a.isT15Supported()) self.assertEqual(str(a), atr)
def stringToByte(string): ''' stringToByte('test') -> [116, 101, 115, 116] converts a string into a list of bytes ''' bytelist = [] for c in string: bytelist.extend( toBytes(c.encode('hex')) ) return bytelist
def stringToByte(string): """ stringToByte('test') -> [116, 101, 115, 116] converts a string into a list of bytes """ bytelist = [] for c in string: bytelist.extend(toBytes(c.encode("hex"))) return bytelist
def exchange(self, apdu, timeout=20000): if self.debug: print("=> %s" % hexlify(apdu)) response, sw1, sw2 = self.device.transmit(toBytes(hexlify(apdu))) sw = (sw1 << 8) | sw2 if self.debug: print("<= %s%.2x" % (toHexString(response).replace(" ", ""), sw)) if sw != 0x9000: raise BTChipException("Invalid status %04x" % sw, sw) return bytearray(response)
def __init__(self, reader, extended=False, debug=False, protocol=None, combi=False): self.reader = reader # Begining Of Line import curses curses.setupterm() self.BOL = curses.tigetstr("cr") + curses.tigetstr("cuu1") # connect to the reader self.connection = reader.createConnection() # create an observer to get debug if debug: observer = ConsoleCardConnectionObserver() self.connection.addObserver(observer) self.BOL = "" # connect using the selected protocol (if any) self.connection.connect(protocol=protocol) # get the ATR self.ATR = self.connection.getATR() # display used protocol protocols = { CardConnection.T0_protocol: "T=0", CardConnection.T1_protocol: "T=1" } print "Using protocol:", protocols[self.connection.getProtocol()] # extended APDU self.extended = extended # select APDU if not extended: if combi: SELECT = toBytes("00 A4 04 00 06 A0 00 00 00 18 50") else: SELECT = toBytes("00 A4 04 00 06 A0 00 00 00 18 FF") expected = [[], 0x90, 0x00] self.transmitAndCompare(SELECT, expected)
def case_4(self, full, apdu): # send data to the card and get response # mode APDU (T=1) # > 80 36 00 09 08 00 01 02 03 04 05 06 07 # < 00 01 02 03 04 05 06 07 08 90 0 # mode TPDU (T=0) # > 80 36 00 09 08 00 01 02 03 04 05 06 07 # < [] 61 9 # > 80 C0 00 00 09 # < 00 01 02 03 04 05 06 07 08 90 0 CASE_2 = toBytes("80 36 00 00 00") print "Case 4" print end = 255 if full: start = 1 else: start = 255 for length_in in range(start, end + 1): print self.BOL, "length:", length_in length_out = length_in + 1 APDU = list(CASE_2) APDU[2] = (length_out & 0xFF00) >> 8 APDU[3] = (length_out & 0x00FF) APDU[4] = length_in APDU += [i for i in range(0, length_in)] if apdu: expected = ([i for i in range(0, length_out)], 0x90, 0x00) self.transmitAndCompare(APDU, expected) else: expected = ([], 0x61, length_out & 0xFF) self.transmitAndCompare(APDU, expected) GET_RESPONSE = toBytes("80 C0 00 00 00") GET_RESPONSE[4] = length_out & 0xFF expected = ([i for i in range(0, length_out)], 0x90, 0x00) self.transmitAndCompare(GET_RESPONSE, expected)
def GetInterfaceMap(self, interface=0): """Returns a list of currently attached interfaces. Key arguments: interface -- the interface class to be returned (default 0 - all) """ A = self.a INS = 0x50 P2 = 0x00 L = 0x00 if interface in range(0,8): P1 = interface else: raise MaximException("Invalid interface.") APDU = self._create_apdu(A, INS, P1, P2, L) data, sw1, sw2 = self._send_apdu( APDU ) parsed = [] if sw1 == 0x90 and sw2 == 0x00: if data[0:1] == [0xE0]: data = toHexString(data[2:]).replace(" ", "").split("C002") for str in data: if str != '': parsed.append(self._decode_interface_map(toBytes(str))) return parsed elif data[0:1] == [0x10]: print("Warning: incorrect list response from GetInterfaceMap().") data = toHexString(data[1:]).replace(" ", "").split("C002") for str in data: if str != '': parsed.append(self._decode_interface_map(toBytes(str))) return parsed elif data[0:1] == [0xC0]: # TODO: Add case for single item response print "finish this section" else: raise MaximException("Invalid response: {0}".format(toHexString(data))) else: self._decode_error_response(sw1, sw2)
def select_data(self, filehex, param_1=0, param_2=4): # Select a data object : filehex is 2 bytes (4 string hex) apdu_command = [ 0x00, 0xA5, param_1, param_2, 0x06, 0x60, 0x04, 0x5C, 0x02, ] + toBytes(filehex) self.send_apdu(apdu_command)
def sc_connect(): global cardservice # detect the smart card based on the content of the ATR (card-centric approach) print('Initializing card connection...') try: cardtype = ATRCardType( toBytes( "3B 90 11 00" ) ) cardrequest = CardRequest( timeout=5, cardType=cardtype ) cardservice = cardrequest.waitforcard() print('Card connection established correctly') except: print('ERROR: Timeout exceeded') sys.exit(0) # connect to the card using T0 protocol. cardservice.connection.connect( CardConnection.T0_protocol )
def __run__(self): #in charge to send commands to the card a send its responses over with the yard stick one try: test = '00A404000E325041592E5359532E4444463031' data, sw1, sw2 = self.cardservice.transmit(toBytes(test)) print(data) wait = 0 old_message = '' while True and data: if wait == 0: print('Sending data...') print(toHexString(data)) self.protocol.send_chat_message(toHexString(data), self.user) wait = 1 if old_message: break else: if len(self.message_queue) > 0: message = self.message_queue[len(self.message_queue) - 1] ms = str(message.data) old_message = ms print('Receiving data: ') print(ms) if ms == 'visa': testaid = '00A4040007A0000000031010' data, sw1, sw2 = self.cardservice.transmit( toBytes(testaid)) wait = 0 self.exit = True self.stop() except KeyboardInterrupt: self.exit = True self.stop()
def verify(self, pin): if self.pin_tries is None: self.get_pin_tries() print 'PIN tries left: %s' % self.pin_tries if not self.pin_tries: raise EMVError('No PIN retries left') assert pin.isdigit() pinhex = pin + 'f' * 14 hexdata = '2%s' % len(pin) + pinhex[:14] resp = self.send(APDU(0, 0x20, 0x61, 0x80, data=toBytes(hexdata))) self.pin_tries = None return resp
def select(self, arg_field, arg_p1_coding, arg_p2_coding): self.__logging.debug("SELECT") if len(arg_field) % 2: self.__logging.debug("Invalid arguments: %s" % (arg_field)) ret_cmd = [0x00] * int(len(arg_field) / 2 + 5) ret_cmd[0] = 0x00 # CLA ret_cmd[1] = 0xA4 # INS ret_cmd[2] = arg_p1_coding # P1 ret_cmd[3] = arg_p2_coding # P2 ret_cmd[4] = int(len(arg_field) / 2) # LC ret_cmd[5:] = toBytes(arg_field.upper()) return ret_cmd
def stringToByte(string): ''' stringToByte('test') -> [116, 101, 115, 116] converts a string into a list of bytes ''' if sys.version_info[0] < 3: bytelist = [] for c in string: bytelist.extend(toBytes(c.encode('hex'))) return bytelist else: if isinstance(string, str): return list(string.encode('ascii')) else: return list(string)
def getDongle(debug=False): dev = None hidDevicePath = None ledger = False if HID: for hidDevice in hid.enumerate(0, 0): if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x2b7c: hidDevicePath = hidDevice['path'] if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x3b7c: hidDevicePath = hidDevice['path'] ledger = True if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x4b7c: hidDevicePath = hidDevice['path'] ledger = True if hidDevice['vendor_id'] == 0x2c97: if ('interface_number' in hidDevice and hidDevice['interface_number'] == 0) or ('usage_page' in hidDevice and hidDevice['usage_page'] == 0xffa0): hidDevicePath = hidDevice['path'] ledger = True if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x1807: hidDevicePath = hidDevice['path'] if hidDevicePath is not None: dev = hid.device() dev.open_path(hidDevicePath) dev.set_nonblocking(True) return HIDDongleHIDAPI(dev, ledger, debug) if SCARD: connection = None for reader in readers(): try: connection = reader.createConnection() connection.connect() response, sw1, sw2 = connection.transmit(toBytes("00A4040010FF4C4547522E57414C5430312E493031")) sw = (sw1 << 8) | sw2 if sw == 0x9000: break else: connection.disconnect() connection = None except: connection = None pass if connection is not None: return DongleSmartcard(connection, debug) if (os.getenv("LEDGER_PROXY_ADDRESS") is not None) and (os.getenv("LEDGER_PROXY_PORT") is not None): return DongleServer(os.getenv("LEDGER_PROXY_ADDRESS"), int(os.getenv("LEDGER_PROXY_PORT")), debug) raise BTChipException("No dongle found")
def transmit(s, conn=None): global gLastErrCode if not conn: conn = gCard.connection if type(s) == str: s = toBytes(s) res, sw1, sw2 = conn.transmit(s) iLoop = 0 while sw1 == 0x61 and iLoop < 32: # max hold 8,192 bytes (32*256) # if sw2 == 0 means auto length second, sw1, sw2 = conn.transmit(GET_RESPONSE + [sw2]) res += second iLoop += 1 return (res, '%02x%02x' % (sw1, sw2))
def getDongle(debug=False, selectCommand=None): if APDUGEN: return HIDDongleHIDAPI(None, True, debug) if not U2FKEY is None: return getDongleU2F(scrambleKey=U2FKEY, debug=debug) if MCUPROXY is not None: return getDongleHTTP(remote_host=MCUPROXY, debug=debug) dev = None hidDevicePath = None ledger = True for hidDevice in hid.enumerate(0, 0): if hidDevice['vendor_id'] == 0x2c97: if ('interface_number' in hidDevice and hidDevice['interface_number'] == 0) or ('usage_page' in hidDevice and hidDevice['usage_page'] == 0xffa0): hidDevicePath = hidDevice['path'] if hidDevicePath is not None: dev = hid.device() dev.open_path(hidDevicePath) dev.set_nonblocking(True) return HIDDongleHIDAPI(dev, ledger, debug) if PCSC: connection = None for reader in readers(): try: connection = reader.createConnection() connection.connect() if selectCommand != None: response, sw1, sw2 = connection.transmit( toBytes("00A4040010FF4C4547522E57414C5430312E493031")) sw = (sw1 << 8) | sw2 if sw == 0x9000: break else: connection.disconnect() connection = None else: break except: connection = None pass if connection is not None: return DongleSmartcard(connection, debug) raise CommException("No dongle found")
def default(self, line): """Process all APDU""" if not line or self.card is None: return try: apdu = toBytes(line) data, sw1, sw2 = self.connection.transmit(apdu) # if INS is A4 (SELECT) then catch and save FID if apdu[1] != 0xA4: return self.sel_obj = toHexString(apdu[5:], PACK) except TypeError as e: print e.message
def requestByATR(atr): print('\n========== REQUEST BY ATR ==========\n') # example: ATR of German ID Card, only works with ISO 14443 devices # cardtype = ATRCardType(toBytes("3B 88 80 01 00 00 00 00 00 00 00 00 09")) cardtype = ATRCardType(toBytes(atr)) # also supports masks # cardtype = ATRCardType( toBytes( "3B 15 94 20 02 01 00 00 0F" ), toBytes( "00 00 FF FF FF FF FF FF 00" ) ) cardrequest = CardRequest(timeout=1, cardType=cardtype) try: cardservice = cardrequest.waitforcard() print('Card detected successfully') return True except smartcard.Exceptions.CardRequestTimeoutException: print('Wrong card type') return False cardservice.connection.connect() print(toHexString(cardservice.connection.getATR()))
class Sam(Card): ATR = toBytes("3B 10 96") MUA = [0x00, 0x82, 0x00, 0x00, 0x10] WRITE2 = [0x00, 0xD0] ENCRIPT = [0x51, 0x33, 0x00, 0x00] LENGTH = [0x09] # byte = [0x00, 0x00] KODE1_PRESENSI = [0x45, 0x4C, 0x48, 0x34, 0x41, 0x33, 0x31, 0x00, 0x00] # XXXAAA100 DF_SAM = [0x40, 0x00] EF_SAM = [0x40, 0x02] LK_SAM = [0x51, 0x36, 0x03, 0x83, 0x08] GC_SAM = [0x00, 0x84, 0x00, 0x00, 0x10] GR_SAM = [0x00, 0xC0, 0x00, 0x00] WK_SAM = [0x07]
def get_adm_key(self, arg_prefix_adm): ret_adm_key = "" while (True): adm_key = input(" " + arg_prefix_adm + " ").strip() if len(adm_key) == 0: break if len(adm_key) == 16: adm_key = adm_key.upper() is_valid = True for i in range(16): if adm_key[i] not in "0123456789ABCDEF": is_valid = False break if is_valid: ret_adm_key = toBytes(adm_key) break return ret_adm_key
def getDongle(debug=False, selectCommand=None): if APDUGEN: return HIDDongleHIDAPI(None, True, debug) if not U2FKEY is None: return getDongleU2F(scrambleKey=U2FKEY, debug=debug) if MCUPROXY is not None: return getDongleHTTP(remote_host=MCUPROXY, debug=debug) dev = None hidDevicePath = None ledger = True for hidDevice in hid.enumerate(0, 0): if hidDevice['vendor_id'] == 0x2c97: if ('interface_number' in hidDevice and hidDevice['interface_number'] == 0) or ('usage_page' in hidDevice and hidDevice['usage_page'] == 0xffa0): hidDevicePath = hidDevice['path'] if hidDevicePath is not None: dev = hid.device() dev.open_path(hidDevicePath) dev.set_nonblocking(True) return HIDDongleHIDAPI(dev, ledger, debug) if PCSC: connection = None for reader in readers(): try: connection = reader.createConnection() connection.connect() if selectCommand != None: response, sw1, sw2 = connection.transmit(toBytes("00A4040010FF4C4547522E57414C5430312E493031")) sw = (sw1 << 8) | sw2 if sw == 0x9000: break else: connection.disconnect() connection = None else: break except: connection = None pass if connection is not None: return DongleSmartcard(connection, debug) raise CommException("No dongle found")
def _sendApdu(self, apduStr): apdu = toBytes(apduStr) print '******' print "Send Apdu", toHexString(apdu) response, sw1, sw2 = self._cardservice.connection.transmit(apdu) print 'Response status', hex(sw1), hex(sw2) print "Response result", toHexString(response) if sw1 == 0x61: print '61' apdu = self.GET_RESPONSE + [sw2] response, sw1, sw2 = self._cardservice.connection.transmit(apdu) print 'Response status', hex(sw1), hex(sw2) print "Response 0x61", toHexString(response) if sw1 == 0x6C: print '6C' apdu = apdu[0:-1] + [sw2] #apdu[0:-1] + [sw2] visa response, sw1, sw2 = self._cardservice.connection.transmit(apdu) print 'Response status', hex(sw1), hex(sw2) print "Response 0x6C", toHexString(response) return response, sw1, sw2
def update(self, observable, actions): (addedcards, removedcards) = actions for card in addedcards: try: cardType = ATRCardType( toBytes( "%s" %toHexString(card.atr) )) cardRequest = CardRequest(timeout = 1, cardType = cardType) cardService = cardRequest.waitforcard() cardService.connection.connect() SELECT = [0xFF, 0xCA, 0x00, 0x00, 0x00] apdu = SELECT #print ("sending" + toHexString(apdu)) response, sw1, sw2 = cardService.connection.transmit( apdu ) #print ('response: ', response, ' status words: ', "%x %x" % (sw1, sw2)) hexUID = self.getParseHexUID(response) #print (hexUID) self.process(hexUID) # id = tagid # print ("UID is",id) except Exception as e: print (e)
def select_file(conn, lfid, contactless=True): res = {} file_id_bytes = scu.toBytes(lfid) command = [0x94, 0xA4, 0x00, 0x00, 0x02] + file_id_bytes data, sw1, sw2 = conn.transmit(command) if not contactless: data, sw1, sw2 = conn.transmit([0x94, 0xC0, 0x00, 0x00]) if sw1 == 0x6C: data, sw1, sw2 = conn.transmit([0x94, 0xC0, 0x00, 0x00, sw2]) if sw1 != 0x90 or sw2 != 0x00: raise Exception("Card error transmit code %02X%02X" % (sw1, sw2)) if data[0] != 0x85 or data[1] != 0x17: raise Exception("Unknown format, received %02X%02X != 8517" % (data[0], data[1])) SFI = data[2] file_types = {0x01: "MF", 0x02: "DF", 0x04: "EF"} file_type = file_types.get(data[3], "Unknown (%02X)" % data[3]) file_eftypes = { 0x00: "directory", 0x02: "linear", 0x04: "cyclic", 0x08: "counter" } file_eftype = file_eftypes.get(data[4], "Unknown (%02X)" % data[4]) numrec = data[6] recsize = data[5] status = data[14] res["sfi"] = SFI res["type"] = file_type res["nature"] = file_eftype res["records"] = numrec res["record_size"] = recsize return res
def transmit(self, cmd): status_code = response = None try: data, sw1, sw2 = self.current_connection.transmit(toBytes(cmd)) status_code = toHexString([sw1, sw2]) response = toHexString(data) # write status to apdu log apdu_request = ">> %s\n" % cmd apdu_response = "<< (%s) %s\n" % (status_code, response) self.txtAPDULog.insertPlainText(apdu_request) self.txtAPDULog.insertPlainText(apdu_response) self.txtAPDULog.insertPlainText("\n") # write status to statusbar status_color = "green" if status_code == '90 00' else "red" self.write_statusbar(status_code, status_color) except CardConnectionException: self.disconnect_picc() return status_code, response
def getDongle(debug=False): dev = None hidDevicePath = None ledger = False for hidDevice in hid.enumerate(0, 0): if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x2b7c: hidDevicePath = hidDevice['path'] if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x3b7c: hidDevicePath = hidDevice['path'] ledger = True if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x4b7c: hidDevicePath = hidDevice['path'] ledger = True if hidDevice['vendor_id'] == 0x2581 and hidDevice['product_id'] == 0x1807: hidDevicePath = hidDevice['path'] if hidDevicePath is not None: dev = hid.device() dev.open_path(hidDevicePath) dev.set_nonblocking(True) return HIDDongleHIDAPI(dev, ledger, debug) if SCARD: connection = None for reader in readers(): try: connection = reader.createConnection() connection.connect() response, sw1, sw2 = connection.transmit(toBytes("00A4040010FF4C4547522E57414C5430312E493031")) sw = (sw1 << 8) | sw2 if sw == 0x9000: break else: connection.disconnect() connection = None except: connection = None pass if connection is not None: return DongleSmartcard(connection, debug) raise BTChipException("No dongle found")
def readUID(self, ATR, apdu): cardtype = ATRCardType(toBytes(ATR)) cardrequest = CardRequest(timeout=None, cardType=cardtype) cardservice = cardrequest.waitforcard() try: cardservice.connection.connect() response, sw1, sw2 = cardservice.connection.transmit(apdu) except CardConnectionException: return None ## print toHexString(cardservice.connection.getATR()) print "%x %x" % (sw1, sw2) print "%x, %x, %x, %x" % (response[0], response[1], response[2], response[3]) if sw1 == 0x90 and sw2 == 0x00: #check if UID was read successfully UID = str(hex(response[0])) + str(hex(response[1])) + str( hex(response[2])) + str(hex(response[3])) return UID.replace("0x", "") return None
def case_3s(self, full): # send data to the card # > 80 32 00 00 07 00 01 02 03 04 05 06 # < [] 90 0 CASE_3 = toBytes("80 32 00 00 00") print "Case 3 short" print end = 255 if full: start = 1 else: start = end expected = ([], 0x90, 0x00) for length in range(start, end + 1): print self.BOL, "length:", length APDU = list(CASE_3) APDU[4] = length APDU += [i for i in range(0, length)] self.transmitAndCompare(APDU, expected)
def write_fp_to_card(write_payload): sc_readers = readers() print(sc_readers) # create a connection to the first reader first_reader = sc_readers[0] connection = first_reader.createConnection() # get ready for a command get_uid = util.toBytes("FF 20 00 00 02 FF FF") try: # send the command and capture the response data and status connection.connect() data, sw1, sw2 = connection.transmit(get_uid) # print the response uid = util.toHexString(data) status = util.toHexString([sw1, sw2]) print("UID = {}\tstatus = {}".format(uid, status)) erase_card(connection) write_card(connection, write_payload) except Exception as e: print(e) print("Operation Failed")
def case_2s(self, full): # gets (1 to 256) data from the card # > 80 34 00 07 07 # < 00 01 02 03 04 05 06 90 0 CASE_2 = toBytes("80 34 00 00 00") print "Case 2 short" print end = 256 if full: start = 1 else: start = end for length in range(start, end + 1): print self.BOL, "length:", length APDU = list(CASE_2) APDU[2] = (length & 0xFF00) >> 8 APDU[3] = length & 0x00FF APDU[4] = length & 0x00FF expected = ([i for i in range(0, length)], 0x90, 0x00) self.transmitAndCompare(APDU, expected)
def select(self): """Select the internal applet and read info.""" APDUapp = [0x00, 0xA4, 0x04, 0x00, len(self.appid) // 2] + toBytes(self.appid) datasel = self.send_apdu(APDUapp) if len(datasel) == 0: raise CryptnoxInvalidException( "This card is not answering any data. Are you using NFC?\n") if len(datasel) != 24: raise CryptnoxInvalidException( "This card is not answering correct select length") # Decoding flags self.cardtype = datasel[0] self.applet_version = datasel[1:4] card_status_bytes = datasel[4] * 256 + datasel[5] self.initialized = bool(card_status_bytes & 64) self.seeded = bool(card_status_bytes & 32) self.pinauth = bool(card_status_bytes & 16) self.pinless = bool(card_status_bytes & 8) self.xpubread = bool(card_status_bytes & 4) self.clearpubrd = bool(card_status_bytes & 2) self.custom_bytes = datasel[8:24] # uintegers list logger.debug("Card Type : %s", chr(self.cardtype)) logger.debug("Applet Version : %s", self.applet_version)
def __verify(self, arg_connection): self.__logging.debug("__verify") try: xml = etree.parse(DEF_SECURITY_CACHE_FOLDER + os.sep + self.__iccid + ".xml") security_root = xml.getroot() pin1_node = security_root.xpath("pin1") self.__pin1 = pin1_node[0].text if self.__pin1_enabled: ret_err, self.__pin1_retry = arg_connection.verify( VERIFY_TYPE.PIN1.value, toASCIIBytes(self.__pin1)) if ret_err == ERROR.ERR_NONE: self.__pin1_verified = True adm_node = security_root.xpath("adm") self.__adm = adm_node[0].text ret_err, self.__adm_retry = arg_connection.verify( VERIFY_TYPE.ADM1.value, toBytes(self.__adm)) if ret_err == ERROR.ERR_NONE: self.__adm_verified = True except: pass
class MustBeEvenException(Exception): pass if __name__ == '__main__': # get and print a list of readers attached to the system sc_readers = readers() print(sc_readers) # create a connection to the first reader first_reader = sc_readers[0] connection = first_reader.createConnection() # get ready for a command get_uid = util.toBytes("FF CA 00 00 00") alt_get_uid = [0xFF, 0xCA, 0x00, 0x00, 0x00] # alternative to using the helper try: # send the command and capture the response data and status connection.connect() data, sw1, sw2 = connection.transmit(get_uid) # print the response uid = util.toHexString(data) status = util.toHexString([sw1, sw2]) print("UID = {}\tstatus = {}".format(uid, status)) except NoCardException: print("ERROR: Card not present")
from smartcard.util import toHexString, toBytes debug = 0 j = 0 r = readers() print "Readers List: %s" % r for i in range(len(r)): if str(r[i]) == "ACS ACR38 Smart Card Reader 00 00" or str( r[i]) == "ACS ACR38U 00 00": j = i connection = r[j].createConnection() connection.connect() select_icc = toBytes("80 A4 08 00 04 3F 00 00 02") select_holder = toBytes("80 A4 08 00 04 3F 00 3F 1C") select_envhol = toBytes("80 A4 08 00 04 20 00 20 01") select_eventlog = toBytes("80 A4 08 00 04 20 00 20 10") select_contractlist = toBytes("80 A4 08 00 04 20 00 20 50") select_contract = toBytes("80 A4 08 00 04 20 00 20 20") select_counters = toBytes("80 A4 08 00 04 20 00 20 69") select_loadlog = toBytes("80 A4 08 00 04 10 00 10 14") select_purchaselog = toBytes("80 A4 08 00 04 10 00 10 15") read_1record = toBytes("80 B2 01 04 1D") read_2record = toBytes("80 B2 02 04 1D") read_3record = toBytes("80 B2 03 04 1D") read_4record = toBytes("80 B2 04 04 1D") read_5record = toBytes("80 B2 05 04 1D") read_6record = toBytes("80 B2 06 04 1D") read_7record = toBytes("80 B2 07 04 1D")
def _to_mifare_key(value): if len(value) != 12: raise ValueError int(value, 16) # also throws ValueError if not a hex string return toBytes(value)
pass else: print 'No challenge length accepted' if authrecords > 0: # follow process at http://www.openscdp.org/scripts/tutorial/emv/readapplicationdata.html raise NotImplementedError() for i in range(start, end + 1): data = tag.emv.read_record_parsed(i, sfi) print data.dump() extra = data.parsed('TRACK2')['extra'] assert extra[-1:] == 'F' # padding assert extra[-2:-1] == '1' # ? is 0 for just-EMV mode assert extra[:5] == '00000' # pin verification field thing = toBytes('0' + extra[5:-2]) print toHexString(thing) # thing appears to be some sort of LSFR? # For ttq of just 0x20, extra is 0000003771940f # Does 1 mean magstripe mode? # NB this is the same as before, but extra is part randomised #print tag.emv.get_data(0x8e) #print tag.emv.get_challenge(0) #tag.emv.verify('0000') #tag.emv.generate_ac(0x40, [], thing) #tag.emv.external_auth() # 9f10 is mandatory, but isn't in any read records.
try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0) if hresult != SCARD_S_SUCCESS: raise error( 'Unable to connect: ' + SCardGetErrorMessage(hresult)) print('Connected with active protocol', dwActiveProtocol) try: if 'winscard' == resourceManager: # IOCTL_SMARTCARD_GET_ATTRIBUTE = SCARD_CTL_CODE(2) hresult, response = SCardControl( hcard, SCARD_CTL_CODE(2), toBytes("%.8lx" % SCARD_ATTR_VENDOR_NAME)) if hresult != SCARD_S_SUCCESS: raise error( 'SCardControl failed: ' + SCardGetErrorMessage(hresult)) r = "" for i in range(len(response)): r += "%c" % response[i] print('SCARD_ATTR_VENDOR_NAME:', r) elif 'pcsclite' == resourceManager: # get firmware on Gemplus readers hresult, response = SCardControl( hcard, SCARD_CTL_CODE(1), [0x02]) if hresult != SCARD_S_SUCCESS:
def UpdateBlock(self, blockNumber, UpData): cmdPrepare = 'ffd600' + blockNumber + '10' + UpData cmdPrepare = utils.toBytes(cmdPrepare) return self.commandToReader(cmdPrepare)
########### COMANDOS PRECARGADOS #################### # | CLA | INS | P1 | P2 | LC | DATA ... selectIAS = [ 0x00, 0xA4, 0x04, 0x00, 0x0C, 0xA0, 0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x01, 0x63, 0x42, 0x00 ] verifyPIN = [0x00, 0x20, 0x00, 0x11, 0x0C] MSE_SET_DST = [0x00, 0x22, 0x41, 0xB6, 0x06] PSO_HASH = [0x00, 0x2A, 0x90, 0xA0, 0x20] PSO_CDS = [0x00, 0x2A, 0x9E, 0x9A, 0x00, 0xFF, 0x00] selectFile = [0x00, 0xA4, 0x00, 0x00, 0x02] getResponse = [0XA0, 0XC0, 0x00, 0x00] readBinary = [0x00, 0xB0, 0x00, 0x00] #################################################### cardtype = ATRCardType( toBytes("3B 7F 94 00 00 80 31 80 65 B0 85 03 00 EF 12 0F FF 82 90 00") ) # Solo eCI de UY #################################################### def enviarAPDU(cmd): print(cmd) data, sw1, sw2 = cardservice.connection.transmit(cmd) print(hex(sw1), hex(sw2)) return [data, sw1, sw2] def encrypt_string(hash_string): sha_signature = hashlib.sha256(hash_string.encode()).hexdigest() return sha_signature
from smartcard.System import readers from smartcard.util import toHexString, toBytes debug = 0 j = 0 r=readers() #print "Readers List: %s" %r for i in range(len(r)): if str(r[i]) == "ACS ACR 38U-CCID 00 00": j = i connection = r[j].createConnection() connection.connect() get_response = [0xFF, 0xC0, 00, 00] antenna_power_on = toBytes("FF 00 00 00 04 D4 32 01 01") antenna_power_off = toBytes("FF 00 00 00 04 D4 32 01 00") set_retry_timer = toBytes("FF 00 00 00 06 D4 32 05 00 00") polling = toBytes("FF 00 00 00 04 D4 4A 01 00") #ultralight deselect_card = toBytes("FF 00 00 00 03 D4 44 01") data,sw1,sw2 = connection.transmit(antenna_power_on) if debug: print "Antenna Power On: %02x %02x" % (sw1,sw2) data,sw1,sw2 = connection.transmit(set_retry_timer) if debug: print "Set Retry Timer: %02x %02x" % (sw1,sw2) data,sw1,sw2 = connection.transmit(polling) if debug:
for zreader in readers: print 'Trying to Control reader:', zreader try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0) if hresult != SCARD_S_SUCCESS: raise error, 'Unable to connect: ' + SCardGetErrorMessage(hresult) print 'Connected with active protocol', dwActiveProtocol try: if 'winscard' == resourceManager: # IOCTL_SMARTCARD_GET_ATTRIBUTE = SCARD_CTL_CODE(2) hresult, response = SCardControl(hcard, SCARD_CTL_CODE(2), toBytes("%.8lx" % SCARD_ATTR_VENDOR_NAME)) if hresult != SCARD_S_SUCCESS: raise error, 'SCardControl failed: ' + SCardGetErrorMessage(hresult) r = "" for i in xrange(len(response)): r += "%c" % response[i] print 'SCARD_ATTR_VENDOR_NAME:', r elif 'pcsclite' == resourceManager and not 'pcsclite-tiger' == resourceManagerSubType: # get firmware on Gemplus readers hresult, response = SCardControl(hcard, SCARD_CTL_CODE(1), [0x02]) if hresult != SCARD_S_SUCCESS: raise error, 'SCardControl failed: ' + SCardGetErrorMessage(hresult) r = "" for i in xrange(len(response)): r += "%c" % response[i] print 'Control:', r
cardtype = AnyCardType() cardrequest = CardRequest(timeout=5, cardType=cardtype) cardservice = cardrequest.waitforcard() cardservice.connection.connect() #get UID #send_print("Card UID: ", [0xFF, 0xCA, 0x00, 0x00, 0x00]) #get ATR #ATR = cardservice.connection.getATR() #print("ATR: {}\n".format(toHexString(ATR))) # Return FCI (file control information) template, optional use of FCI tag and length send_print("SELECT by DF_name (command always the same)", toBytes("00 a4 04 00 0a a0 00 00 04 40 00 01 01 00 01 00") ) # this command is constant send_print( "HID Seos proprietary command (command always the same, response always* different)", toBytes( "80 a5 04 00 2a 06 12 2b 06 01 04 01 81 e4 38 01 01 02 01 18 01 01 91 75 05 06 14 2b 06 01 04 01 81 e4 38 01 01 02 01 18 01 01 81 23 91 26 01 00" )) send_print( "Start General authentication (EXTERNAL AUTHENTICATE - an entity in the card authenticates an entity in the outside world) \n(command always the same, response always* different)", toBytes("00 87 00 01 04 7c 02 81 00")) send_print( "Continue General authentication (Response from the outside world and verification by the card) (command always* different, response always* different)", toBytes(
#--------------------------------------------------- ''' flddict['4F'].append('A000000333010102') flddict['4F'].append('A000000333010106') ''' ''' user chose the AID ''' aidIdx = choiceAID(flddict['4F']) ''' select AID, get file control info ''' capdu.cla = cmdset.ApduCmdSet.PBOC_SELECT[:1] capdu.ins = cmdset.ApduCmdSet.PBOC_SELECT[1:] capdu.lc = [len(flddict['4F'][aidIdx])/2] capdu.data= toBytes(flddict['4F'][aidIdx]) ''' p1 : 0x04 - selected by name ''' capdu.p1 = [0x04] ''' p2 : 0x00 - the first or only one ''' capdu.p2 = [0x00] capdu.le = [0x00] AID_select_cmd = capdu.packCapdu() response, sw1sw2 = session.sendApdu(AID_select_cmd) print 'SELECT AID :\n> capdu = [%s]\n< response = [%s] sw1sw2 = [%s]' % (toHexString(AID_select_cmd),response, sw1sw2) flddict = {} flddict = parse(response, flddict) #showDictData(flddict)
def readBlock(self, Block): cmdPrepare = 'ffb000' + Block + '10' #firstBlocks cmdPrepare = utils.toBytes(cmdPrepare) return self.commandToReader(cmdPrepare)
print 'Trying to Control reader:', zreader try: hresult, hcard, dwActiveProtocol = SCardConnect( hcontext, zreader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0) if hresult != SCARD_S_SUCCESS: raise error('Unable to connect: ' + SCardGetErrorMessage(hresult)) print 'Connected with active protocol', dwActiveProtocol try: if 'winscard' == resourceManager: # IOCTL_SMARTCARD_GET_ATTRIBUTE = SCARD_CTL_CODE(2) hresult, response = SCardControl( hcard, SCARD_CTL_CODE(2), toBytes("%.8lx" % SCARD_ATTR_VENDOR_NAME)) if hresult != SCARD_S_SUCCESS: raise error( 'SCardControl failed: ' +\ SCardGetErrorMessage(hresult)) r = "" for i in xrange(len(response)): r += "%c" % response[i] print 'SCARD_ATTR_VENDOR_NAME:', r elif 'pcsclite' == resourceManager and \ not 'pcsclite-tiger' == resourceManagerSubType: # get firmware on Gemplus readers hresult, response = SCardControl( hcard, SCARD_CTL_CODE(1), [0x02]) if hresult != SCARD_S_SUCCESS: raise error(
def hex2gb2312(hexStr): #将十六进制转换为gb2312字符 # example: 494342432041544D ==> ICBC ATM return bytes(toBytes(hexStr)).decode('gb2312')
#! /usr/bin/env python from smartcard.System import readers from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver from smartcard.util import toBytes, toHexString import logging # Initialize logging. logging.basicConfig(filename='nfc.log', level=logging.INFO) # Define the APDUs used in this script CMD_SERIAL_ID = toBytes("80 14 00 00 08") CMD_CARD_ID = toBytes("80 14 04 00 06") CMD_NFC_SCAN = toBytes("ff 00 00 00 06 D4 60 01 01 00 20") GET_RESPONSE = toBytes("FF C0 00 00 FF") debug = False # get all the available readers readers = readers() print "Available readers:", readers connections = list() for reader in readers: print "Initializing reader:", reader connection = reader.createConnection() connection.connect() connections.append(connection)
根据PBOC规范说明检查发卡行证书 ''' try: certificate['ISSUE'].certificateCheck() except Exception,e: raise Exception(e) ''' 重新计算HASH ''' #certificate['ISSUE'].showCertificate() srcdata = certificate['ISSUE'].__str__() srcdata = srcdata[2:len(srcdata) - 42] if icFldSet.has_key('92'): srcdata += icFldSet['92'] srcdata += icFldSet['9F32'] hashmessage = ''.join(map(chr, toBytes(srcdata))) hashvalue = toHexString(map(ord, list(Hash(hashmessage, 'SHA-%d' % int(certificate['ISSUE'].hashAlgId, 16)))), format=1) if hashvalue != certificate['ISSUE'].hashVal: raise Exception('终端计算hash[%s]与证书hash[%s]不一致' % (hashvalue, certificate['ISSUE'].hashVal)) print '发卡行公钥证书恢复成功,终端计算hash[%s]与证书hash[%s]一致' % (hashvalue, certificate['ISSUE'].hashVal) ''' 检验发卡行标识是否匹配主账号最左面的3-8个数字 ''' issueId = certificate['ISSUE'].issueId.rstrip('F') if len(issueId) not in range(3, 9): raise Exception('发卡行标识需至少3个数字与主账号左边3个数字一致') if icFldSet['5A'][0:len(issueId)] != issueId: raise Exception('发卡行标识[%s]与主账号左%d位[%s]不一致' % (icFldSet['5A'][0:len(issueId)], len(issueId), issueId)) '''