How to send APDU to Mifare Classic 1k card?

2019-03-16 08:41发布

问题:

What I am trying to achieve is to send APDU command to MIFARE Classic 1K card to change its A and B keys.

I was able to establish a connection with the card and use a default key (FFFFFFFFFFFF) to read block 0 and block 1. I used HID MifareSamples application for it.

Now, I would like to change A key from default to something else. I found a solution here, at stackoverflow (Mifare Change KEY A and B) which suggests that I have to send this APDU:

New key A = 00 11 22 33 44 55 Access bits not overwritten Key B not used (so FF FF FF FF FF FF)

=> Write to Sector Trailer 00 11 22 33 44 55 FF 0F 00 FF FF FF FF FF FF FF

I found a good tool JSmartCard Explorer which allows you to send APDUs to cards. Then I read PCSC specifications 3.2.2.1.4 Load Keys Command chapter and understood that the command should probably look like this:

FF 82 00 00 18 00 11 22 33 44 55 FF 0F 00 FF FF FF FF FF FF FF

But unfortunately JSmartCard tool fails with "Command not allowed (no current EF)".

What I am doing wrong? How can I change the key?

回答1:

First of all, MIFARE Classic cards do not use APDU commands. Hence, you do not send APDUs to the card but to the card reader (which translates them into MIFARE Classic commands). APDU commands to be processed by the reader typically start with the class byte FF.

In MIFARE Classic cards, the keys (A and B) and the access conditions for each sector are stored in the sector trailer (the last block of each sector). A MIFARE Classic 1K card has 16 sectors with 4 blocks each.

So if you want to set the keys & access conditions for sector 0, you would need to write them to block 3 (the last block of sector 0). The PC/SC standard defines the write command (UPDATE BINARY) for storage cards as:

FF D6 XXYY 10 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Where XXYY is the block address and ZZ... is the data to be written to the block.

The format of the sector trailer is (see this answer for further details):

<key A> | access bits | general purpose byte | <key B>

So in order to set

  • key A = 00 11 22 33 44 55
  • key B = 66 77 88 99 AA BB
  • access bits = 787788 (sector trailer is writable using key B only; access bits/GPB can be read with key A or B; data blocks are writable using key B only; data blocks can be read with key A or B)
  • GPB is set to 69

for sector 0, you would use the following write command:

FF D6 0003 10 001122334455 787788 69 66778899AABB

Note that you cannot partially update the sector trailer, you always have to construct and write the whole sector trailer.