I want to do this to protect the card from erasable or cloning the card. I read many documents Some tell the user the fourth block to set permission to reading and write..
According to @Michael Roland
The authentication keys and the access conditions for each sector of a MIFARE card are located in the last block of that sector (the sector trailer). You can update this block with new access conditions and authentication keys using a regular write command.
The sector trailer looks like this:
+-----------------------------+--------------+----+-----------------------------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
+-----------------------------+--------------+----+-----------------------------+
| Key A | Access Bits | GP | Key B |
| (6 bytes) | (3 bytes) | B | (6 bytes) |
+-----------------------------+--------------+----+-----------------------------+
So the access bits are located in byte 6-8 and look like this:
+-------+-------+-------+-------+-------+-------+-------+-------+
| Bit 0 | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Byte 6: | nC2_3 | nC2_2 | nC2_1 | nC2_0 | nC1_3 | nC1_2 | nC1_1 | nC1_0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Byte 7: | C1_3 | C1_2 | C1_1 | C1_0 | nC3_3 | nC3_2 | nC3_1 | nC3_0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Byte 8: | C3_3 | C3_2 | C3_1 | C3_0 | C2_3 | C2_2 | C2_1 | C2_0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Where nCx_y = not Cx_y and "C1_x, C2_x, C3_x" is the access condition for block x:
C1_3, C2_3, C3_3: sector trailer (block 3 in this sector)
C1_2, C2_2, C3_2: block 2 in this sector
C1_1, C2_1, C3_1: block 1 in this sector
C1_0, C2_0, C3_0: block 0 in this sector
How I perform this in my ongoing project
You can t protect a card to be replicate on herself. (A force brut method is easy to apply on this technologie)
What is possible to do is a hash of all block including UID that you store on the card.In your programm you just compare data hash with the hash stored.
To realise your very basic hash in python and store it in a block, you can use double pseudo random:
def CRYPT_hashage(data,UID):
seed(str(data)+str(UID))
seed(random())
return str(random()).replace("0.","")[:8]
It prevent from clonning on another card. The user still can modify it own card. But you can hash the 'sensitives' data with the same technique.
After theses 2 securities, it left only the "cloning on herself" technique, for example: - You copy your datas - You pay (for a cashless paiement system) - You paste your olds datas on your card)
The only way to prevent it is to store all datas on a server using only the UID of the card as a primary key.
There exist card that you can change UID.
You can protect every sector with a key A or key B.
That said, Mifare Classic cards security is broken at this point. You're not going to be able to protect anything really.
Finally, I solved this solution
For this, we need to change the access bits in each sector on Fourth block
For Example on Sector 5
Just like for sector 5 we need to change access bits on 23 blocks of it's
We need to first authenticate the sector 5...
The Default key is
byte keya[] = { (byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF,(byte) 0xFF};
Which is 000000000000FF078069FFFFFFFFFFFF
the First Bit 6 is for Key A which is 000000000000 and last 6 his for key B which is FFFFFFFFFFFF hex string
FF078069 hex string is access bits
so for change this we need to implementation like this for the first time we need to authenticate with default key
MifareClassic mfc = MifareClassic.get(tag);
try {
mfc.connect();
auth = mfc.authenticateSectorWithKeyA(5,
MifareClassic.KEY_DEFAULT);
if(auth)
{
String nkeya = "key123";// 6 length only
nkeya = toHex(nkeya).toUpperCase();
nkeya = nkeya.substring(28,40);
String nkeyb = "key123"; // 6 length only
nkeyb = toHex(nkeyb).toUpperCase();
nkeyb = nkeyb.substring(28,40);
String nkey = nkeya+"FF078069"+nkeyb;
int len = nkey.length();
byte[] nkeyab = new BigInteger(nkey, 16).toByteArray();
// 5 is sector and 5*4+3 is fourth block of sector 5
mfc.writeBlock((5*4)+3,nkeyab);
}
catch(Execption e)
{
}
After successfully write protection Default Authentication is failed So we need to authenticate with Access key which we create
try {
MifareClassic mfc = MifareClassic.get(tag);
String key = getKeya();
key = toHex(key).toUpperCase();
int len = key.length();
key = key.substring(28,40);
keya = new BigInteger(key, 16).toByteArray();
//for key A or for Keb b
mfc.connect();
auth = mfc.authenticateSectorWithKeyA(5, keya);
if(auth)
{
byte[] readblock4= mfc.readBlock(20);
}
}
catch(Exeption e)
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With