1

In the following you see a snippet of my Python program that I wrote to send APDU commands to smart cards. I used PySCard library in this program.

First Program :

for LOAD_KEY in validLoadCommands:
    data,sw1,sw2 =connection.transmit(LOAD_KEY)
    temp = LOAD_KEY
    x= temp[3]
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=hex(LOAD_KEY[j])
    print '   >>>',' Load Command :',
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=str(LOAD_KEY[j])
        if len(LOAD_KEY[j])==3:
            LOAD_KEY[j]=LOAD_KEY[j][0:2]+'0'+LOAD_KEY[j][2]
        print LOAD_KEY[j],
    print
    for j in range(0,len(data)):
        data[j]=hex(data[j])
    print '   <<<',' Data :',
    for j in range(0,len(data)):
        data[j]=str(data[j])
        if len(data[j])==3:
            data[j]=data[j][0:2]+'0'+data[j][2]
        print data[j],
    print '--',hex(sw1),hex(sw2)

    if (temp[2] == 0x00 or temp[2] == 0x20):
        keyType = 0x60
    else:
        keyType = 0x61

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,temp[3]]
    print 'AUTH Command: ', AUTH
    data,sw1,sw2 =connection.transmit(AUTH)
    print data, sw1, sw2

And its output :

Auth Command: [255, 134, 0, 0, 5, 1, 0, 4, 97, '0x0e']

Traceback (most recent call last):
  File "C:\Users\Erb4h1m\Desktop\Faraadis Alborz Card Reader\CRT-603-CZ1_Read1Block.py", line 199, in <module>
    data,sw1,sw2 =connection.transmit(AUTH)
  File "D:\Software\Python27\lib\site-packages\smartcard\CardConnectionDecorator.py", line 82, in transmit
    return self.component.transmit(bytes, protocol)
  File "D:\Software\Python27\lib\site-packages\smartcard\CardConnection.py", line 140, in transmit
    data, sw1, sw2 = self.doTransmit(bytes, protocol)
  File "D:\Software\Python27\lib\site-packages\smartcard\pcsc\PCSCCardConnection.py", line 173, in doTransmit
    hresult, response = SCardTransmit(self.hcard, pcscprotocolheader, bytes)
  File "D:\Software\Python27\lib\site-packages\smartcard\scard\scard.py", line 1329, in SCardTransmit
    return _scard.SCardTransmit(*args)
TypeError: Expected a list of bytes.

And when I replace temp[3] with x:

for LOAD_KEY in validLoadCommands:
    data,sw1,sw2 =connection.transmit(LOAD_KEY)
    temp = LOAD_KEY
    x= temp[3]
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=hex(LOAD_KEY[j])
    print '   >>>',' Load Command :',
    for j in range(0,len(LOAD_KEY)):
        LOAD_KEY[j]=str(LOAD_KEY[j])
        if len(LOAD_KEY[j])==3:
            LOAD_KEY[j]=LOAD_KEY[j][0:2]+'0'+LOAD_KEY[j][2]
        print LOAD_KEY[j],
    print
    for j in range(0,len(data)):
        data[j]=hex(data[j])
    print '   <<<',' Data :',
    for j in range(0,len(data)):
        data[j]=str(data[j])
        if len(data[j])==3:
            data[j]=data[j][0:2]+'0'+data[j][2]
        print data[j],
    print '--',hex(sw1),hex(sw2)

    if (temp[2] == 0x00 or temp[2] == 0x20):
        keyType = 0x60
    else:
        keyType = 0x61

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType, x]
    print 'AUTH Command: ', AUTH
    data,sw1,sw2 =connection.transmit(AUTH)
    print data, sw1, sw2

Then the output is:

AUTH: [255, 134, 0, 0, 5, 1, 0, 4, 97, 14]
[] 144 0

As you see above, in the second case I DON'T receive any error, while there is no difference between first program and second program! I only replaced

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,temp[3]]

with:

    AUTH = [0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, blockNum, keyType,x]

and x is initialized with temp[3] in the top of program. neither x nor temp[3] didn't changed between the line of initialization and the line of error.

What is going here?

5
  • 2
    Why are you converting your lists of ints into lists of strings? All it seems to be doing is causing you a headache. For instance, you if statement will always fail as you testing for equality between a string and an int. Commented Jul 27, 2015 at 9:13
  • 1
    If you really want to create strings for printing then only convert them when you need to print them (and don't modify the list). "0x{:0>2x}".format(10) produces "0x0a". The bit between the braces is the format specifier for your number. The colon denotes talking about how to format the argument. 0>2 align the number on the right, padding up to at least two characters (if needed) with zeros. The x means to format the number in hexadecimal. Commented Jul 27, 2015 at 9:25
  • @Dunes When I change LOAD_KEY in the program, does the value of temp change also? Commented Jul 27, 2015 at 9:39
  • 2
    Yes. Because LOAD_KEY and temp are the same list object in memory. Perhaps you want temp to be a copy of LOAD_KEY. Use temp = list(LOAD_KEY) or temp = LOAD_KEY[:] to create a copy. Commented Jul 27, 2015 at 9:45
  • @Dunes Your comments must written in gold! :) Those are really useful. Thank you. Commented Jul 27, 2015 at 9:49

2 Answers 2

2

Your temp variable reference LOAD_KEY (Line 3: temp = LOAD_KEY)

When x= temp[3] get called, it's the value of LOAD_KEY at index 3 right after your connection.transmit that is set.

When you are sending temp[3] for your AUTH, LOAD_KEY have changed and so does temp[3]. So it's not anymore the same value as x.

connection.transmit => LOAD_KEY is set => temp => [3] => x
*** LOAD_KEY changes ***
x => old value of temp[3] aka LOAD_KEY[3]
temp[3] => whatever your code have put in it

Edit: short example

>>> LOAD_KEY = ['one', 'two', 'three', 'four']
>>> temp = LOAD_KEY
>>> x = temp[3]
>>> LOAD_KEY[3] = 'new value'
>>>
>>> LOAD_KEY[3]
'new value'
>>> temp[3]
'new value'
>>> x
'four'
Sign up to request clarification or add additional context in comments.

3 Comments

Your temp variable reference LOAD_KEY (Line 3: temp = LOAD_KEY) So when I change LOAD_KEY, the value of temp also change?
In the line x= temp[3] the x variable reference temp[3]. So when I change LOAD_KEY the value of temp will change automatically, and when temp change, the value of temp[3] and x variable will change automatically, Am I right?
See my edit for a comprehensible (hopefully) example.
2

In you first example, temp[3] is a string ('0x0e').

In your second example, x is an integer (14).

This is because you're converting the integer values of the LOAD_KEY list to an hexadecimal string with the following line:

LOAD_KEY[j] = hex(LOAD_KEY[j])

In order to convert a string in hexadecimal representation to an integer, use the second argument of the built-in type int to set the base to 16:

>>> int('0x0e', 16)
14

2 Comments

You are right too, probably a mistake at line 9 LOAD_KEY[j]=str(LOAD_KEY[j])
The conversion to a string is earlier than that -- LOAD_KEY[j]=hex(LOAD_KEY[j]). The conversions seem to be entirely redundant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.