Mifare 4K change of keys in trailing block returns error "99" using ACR1252 and pyscard

461 views Asked by At

We receive Mifare 4k cards from a supplier who pre-encodes each sector trailer as follows:

FFFFFFFFFFFFFF078069FFFFFFFFFFFF

In doing so, the supplier sets the access bit to FF0780 and the read key (Key A) and write key (Key B) remain the factory default FFFFFFFFFFFF

When attempting to write a new read key(Key A) and write key (Key B) and access bit using pyscard and encoder ACR1252, I'm getting response code "99" which is an undocumented error code. I assume this is happening because the access bit has been changed as blank cards directly from the factory do not generate this error.

In this example we update the trailer block such that Key A and Key B are FFFFFFFFFFFF and the access bit is 787788:

write_data = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x77, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
write_key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
# load write key
_, response_code, _ = cardservice.connection.transmit([0xFF, 0x82, 0x00, 0x01, 0x06, *write_key])
# authenticate write key
_, response_code, _ = cardservice.connection.transmit([0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, block, 0x61, 0x01])
# write data
_, response_code, _ = cardservice.connection.transmit([0xFF, 0xD6, 0x00, block, 0x10, *write_data])

Any idea why response code 99 is returned for card where the supplier has set the access bit?

Note: the authentication works ok, it's just the write step that fails.

1

There are 1 answers

0
Ajax On BEST ANSWER

Turns out the access bit subsequently set by the supplier ff0780 means you need to authenticate the read_key (Key A) in order to write to the trailer block. Very counterintuitive, but works for Mifare 4K card where the access bit was previously set to ff0780:

write_data = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x78, 0x77, 0x88, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
read_key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
# load read key
_, response_code, _ = cardservice.connection.transmit([0xFF, 0x82, 0x00, 0x00, 0x06, *read_key])
# authenticate read key
_, response_code, _ = cardservice.connection.transmit([0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, block, 0x60, 0x00])
# write data
_, response_code, _ = cardservice.connection.transmit([0xFF, 0xD6, 0x00, block, 0x10, *write_data])

I also found you need to authenticate the key immediately prior to writing. Authenticating both keys, reading then writing returned the same 99 response code. Also, it appears the error code 99 is being cascaded up from the Mifare IC, as opposed to the card reader, which is why error code 99 does not appear in the ACR1252 documentation.

I found the following documents helpful: