Search code examples
pythonauthenticationapdumifarecontactless-smartcard

How to access MIFARE 1k memory blocks with Gemalto Prox-SU reader?


I have just recently jumped into smartcard programming.

I am using Gemalto Prox-SU reader and have several blank MIFARE Classic 1k cards available, on a Ubuntu 16.04 machine. I have installed the Gemalto Prox-SU reader and got the reader to detect a card through a script in python using Ludovic Russeau's pyscard.

I have managed to write a script which sends APDUs to the reader/card connection. I can read ATR, send GetData command to read card's serial number and have been trying to send several APDUs to the card to try and read the card memory blocks. Aside from LoadKey commands, however, everything else is returning "0x6982: security status not satisfied"

I know I am supposed to send a General Authentication command before every read and write, as stated in the manual, but even General Authenticate command is returning "security status not satisfied". From what I have been reading this should be really simple. What am I missing? How to set up my script so that authentication succeeds and I can read data from the memory blocks?


Solution

  • The typical flow for reading MIFARE Classic 1K cards with the Prox-SU reader (see the manual) is:

    1. Load an authentication key. For instance, if your card is readable using key A with the default value ("transport key") FF FF FF FF FF FF, you would use the following LOAD KEY command:

      FF 82 00 50 06 FFFFFFFFFFFF
            ^^ ^^    ^^^^^^^^^^^^
             |  |               \-- Key
             |  |
             |  \------------------ Key slot 80 (0x50)
             |
             \--------------------- Key in RAM (0x00)
      

      This stores the key FF FF FF FF FF FF into the first key slot (0x50) in volatile memory (RAM) of the reader.

    2. Authenticate to a sector using the GENERAL AUTHENTICATE command. Eventhough you authenticate to the whole sector you need to address the sector by a block number (typically the first block of the sector):

      FF 86 00 00 05 01 0004 60 50
                        ^^^^ ^^ ^^
                           |  |  \-- Key slot 80 (0x50)
                           |  |
                           |  \----- Key type (0x60 = Key A, 0x61 = Key B)
                           |
                           \-------- Block number (block 4)
      
    3. Finally, you can read a block using the READ BINARY command:

      FF B0 0004 10
            ^^^^
               \-------- Block number (block 4)
      

    If you receive a status code 69 82 during GENERAL AUTHENTICATE, this most likely indicates that you try to authenticate with an incorrect key.