A couple of guys asked me to create a simple python script to allow the iClass cards to be read and extract their UID to control a few other devices. I thought of sharing with you since there are a few other people asking for the same on the Internet.

from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.util import toHexString, toBytes
from smartcard.CardMonitoring import CardMonitor, CardObserver
from smartcard.util import *
import urllib2
import time
 
class printobserver( CardObserver ):
    """A simple card observer that is notified
    when cards are inserted/removed from the system and
    prints its uids. The code is not pretty but it works!
    """
 
    def update( self, observable, (addedcards, removedcards) ):
        apdu = [0xff, 0xca, 0, 0, 0]
        for card in addedcards:
          try:
            cardtype = AnyCardType()
            cardrequest = CardRequest( timeout=1, cardType=cardtype )
            cardservice = cardrequest.waitforcard()
            cardservice.connection.connect()
            response, sw1, sw2 = cardservice.connection.transmit(apdu)
            tagid = toHexString(response).replace(' ','')
            print tagid
            #urllib2.urlopen("http://your_web_servers_waiting_for_card_data/?uid=%s" % tagid, None, 3)
          except Exception as e:
            print "Exception detected: %s" % e
 
print "Card Monitor started..."
cardmonitor = CardMonitor()
cardobserver = printobserver()
cardmonitor.addObserver( cardobserver )
while True:
  time.sleep(3600)

It was tested using an Omnikey 5321 v2 USB reader and it was working perfectly. I know that I’m doing two calls to the device (the first one detects it and the second one requests the UID) and this could probably be done in a single pass. If you know how to do it, please step forward 🙂

PS: It was also shared on github: https://gist.github.com/zatarra/75df47c8bd5a8d913cb4