Skip to content

Instantly share code, notes, and snippets.

@gazambuja
Last active June 6, 2018 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gazambuja/a55b75422a5a18c50e6d1ba7f5f44eea to your computer and use it in GitHub Desktop.
Save gazambuja/a55b75422a5a18c50e6d1ba7f5f44eea to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import hashlib, sys, time, json
from smartcard.CardType import ATRCardType, AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.CardConnection import CardConnection
from smartcard.util import toHexString, toBytes
action = error = userpin = stringhash = False
GET_RESPONSE = [0x00, 0xB0]
SELECT = [0x00, 0xA4, 0x04, 0x00, 0x0C, 0xA0, 0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x01, 0x63, 0x42, 0x00, 0x00]
TRYPIN = [0x00, 0x20, 0x00, 0x11, 0x0C]
USERID = [0x00, 0xA4, 0x00, 0x00, 0x02, 0x70, 0x02]
jsonarr = []
def output(data, error = False):
print json.dumps({'action': action, 'error': error, 'data': data})
exit()
if( len(sys.argv) == 1 ):
output(False, "Faltan argumentos");
else:
action = sys.argv[1]
userpin = sys.argv[2] if len(sys.argv) > 3 else False
stringhash = sys.argv[3] if len(sys.argv) > 3 else False
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
cardrequest = CardRequest( timeout=20, cardType=cardtype )
if (len(cardrequest.getReaders()) == 0 ):
output(False,"Lector no conectado")
def toUnicode(data):
result = ''
if isinstance(data, list):
for d in data:
result += unicode(chr(d),"utf-8")
else :
result = data
return result.encode('ascii',errors='ignore').replace(u"\u0011", "").replace(u"\u0017", "").strip()
def encrypt_string(hash_string):
sha_signature = hashlib.sha256(hash_string.encode()).hexdigest()
return sha_signature
def runCommand(cmd):
data, sw1, sw2 = cardservice.connection.transmit(cmd)
return [data, sw1, sw2];
def getData(cmd, offset):
data, sw1, sw2 = runCommand(cmd)
data, sx1, sx2 = runCommand(GET_RESPONSE + offset + [sw2])
if( len(data) == 0 ):
return [False, False, False]
else :
nextOffset = data[2] + 3
return [data, data[1], nextOffset];
def showInfo(data, tag, offset):
datastring = toUnicode( data[3:data[2] + 3] )
if( datastring != '' and datastring != ' ' ):
jsonarr.append("\"tag" + hex(tag) + "\":\"" + datastring + "\"")
def toHex(str):
m = len(str)
lst = []
for i in xrange(0, m, 2):
lst.append( int('0x' + str[i] + str[i + 1], 16) )
return lst
def toPinHex(pin):
m = len(pin)
lst = []
for i in xrange(0, 12, 1):
if(i >= m):
lst.append( int('0x00', 16))
else:
lst.append( int('0x3' + pin[i], 16))
return lst
def getUserData():
lastOffset = 0x00
while True:
data, tag, nextOffset = getData( USERID, [0x00, lastOffset] )
if ( data == False and tag == False and nextOffset == False ) :
break
else :
showInfo(data, tag, lastOffset)
lastOffset = lastOffset + nextOffset
if ( len(jsonarr) > 0 ):
return jsonarr
else:
return False
def init():
# print "Esperando..."
global cardservice
cardservice = cardrequest.waitforcard()
cardservice.connection.connect( CardConnection.T0_protocol )
# Connect to reader and eDocument
data, val1, val2 = runCommand( SELECT )
if ( val1 != 0x90 and val2 != 0x0 ) :
output(False,"ERROR AL LEER DOCUMENTO")
else:
time.sleep(1)
data, val1, val2 = runCommand( TRYPIN + toPinHex(userpin) )
if ( val1 == 0x90 and val2 == 0x0 ) :
if ( getUserData() ):
data, val1, val2 = runCommand( [0x00, 0xA4, 0x04, 0x00, 0x0c, 0xA0, 0x00, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x01, 0x63, 0x42, 0x00, 0x00] )
data, val1, val2 = runCommand( [0x00, 0x22, 0x41, 0xB6, 0x06, 0x84, 0x01, 0x01, 0x80, 0x01, 0x02] )
data, val1, val2 = runCommand( [0x00, 0x2A, 0x90, 0xA0, 0x20, 0x90, 0x19] + MYHASH )
data, val1, val2 = runCommand( [0x00, 0x2A, 0x9E, 0x9A, 0x00, 0xFF, 0x00] )
jsonarr.append("\"hashrecived\":\"" + stringhash + "\"")
jsonarr.append("\"hashsigned\":\"" + encrypt_string(toHexString(data).replace(" ", "")) + "\"")
output( json.loads("{" + ",".join(jsonarr) + "}"))
else:
output(False,"ERROR AL OBTENER DATOS")
print data, val1, val2
else :
output(False,"PIN INVALIDO")
if ( action == 'readertry' ):
output( {"reader": str(cardrequest.getReaders()[0]) } )
elif ( action == 'getData' ):
MYHASH = toHex( encrypt_string(stringhash) )
init()
else:
output(False, "ACTION NOT DEFINED")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment