Click here to Skip to main content
12,691,789 members (27,271 online)
Click here to Skip to main content
Add your own
alternative version


15 bookmarked

A .NET MiFare Helper Class

, 8 Jan 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
This article introduces a .NET class that makes the use of MiFare card easier.


MIFare is a technology that allows a contactless transmission of data between a battery-less memory card and a card reader. MiFare is widely used for ticketing (Oyster card at London underground) or for access control. The helper class introduced in this article aims to simplify the use of MiFare memory cards in a .NET application. In particular, the helper class implements the following features:

  1. Read/write of MiFare card data blocks
  2. Set up of read/write permissions and card keys
  3. Application directory (MAD) management


There are several flavors of MiFare memory cards. This article addresses the so-called MiFare classic, which are shipped in two sizes: 1 kilobytes and 4 kilobytes. The 1K memory card is organized in 16 sectors. Each sector is made up of 4 datablocks, and each datablock is 16 bytes in size. The 4th datablock stores read and write permissions for each of the remaining 3 datablocks. The 4th datablock also stores the access keys. According to MiFare specifications, two keys exists, named keyA and keyB. Each key can be granted a different set of operations on the datablocks. Datablocks in a sector can be read or written only after the application as successfully logged in into the sector with the proper key. The 4K memory card is organized in a similar way. There are 40 sectors. The first 32 sectors have 4 datablocks, the remaining 8 have 16 datablocks. The first datablock of sector 0 stores some read-only manufacturer information. The other 2 datablocks in sector 0 store the MiFare application directory (MAD). An application directory says which application used each sector on the card. The application is identified by a unique identifier registered to a Mifare authority. MAD in sector 0 handles applications in sectors from 1 to 15. There is another MAD (called MAD2) stored in sector 16 that handle sectors from 17 to 39.

Using the Code

The MiFare helper class aims to simplify the use of a MiFare in a .NET application.


To instantiate a MiFARECard class, just call the constructor passing an instance to an object that implements the ICardReader interface. The ICardReader interface decouples the MiFareCard from the physical implementation of the MiFare card reader. The ICardReader interface defines the following methods:

MiFARECard card = new MiFARECard(new FileCardReader(“test.txt”));

The FileCardReader is a class that implements the ICardReader interface and simplifies the test of MiFARECard class. The FileReaderCard class reads and writes data from a text file on disk. This makes it easy to test the helper class even if a MiFare reader is not available.

Read/Write of Datablocks

To read data from cards, the MiFareCard class implements two mechanisms:

  1. Call the GetData/SetData methods of the MiFARECard class. This methods allows to write data of any length. The MiFARECard class will take care to login into the proper sectors are required. Trailer sectors are not overwritten.
    MiFARECard card = new MiFARECard(new FileCardReader(“test.txt”));
    // read a block of data. The MiFARECard object will take care to login into
    // the proper sectors
    Byte[] data = card.GetData(sector, datablock, 64);
    // change data here..
    // write data into MiFARECard class internal members
    card.SetData(sector, datablock, data);
    // write changes on card
  2. Call the GetSector method on the MiFare card. This method returns a Sector object. On this object, you can then call the GetData/SetData method to get the content of a given datablock.
    MiFARECard card = new MiFARECard(new FileCardReader(“test.txt”));
    // load the sector of interest
    Sector s = card.GetSector(sector);
    // read data from the datablock
    Byte[] data = s.GetData(datablock);
    // changes data. Because GetData do not make copies of internal data,
    // any changes to the data array is automatically reflected into the sector
    for (int i=0; i<data.Length; i++)
      data[i] = (byte)0x11;
    // write changes back to the card

    Note that to write back changes on card, call the Flush method. This method will take care to write on disk only the datablocks that have actually changed.

Set Up Sector Permissions

To set up sector permissions, the Sector class provides a property named AccessConditions. The AccessConditions class exposes a property (DataAreas) that allows the application to set, for each datablock, the permissions (Never, KeyA, KeyB, KeyAOrB) for each operation (Read, Write, Increment, Decrement). AccessConditions class also allows the application to set keys A and B, and also to set whether the MAD is in use or not.

Sector sector0 = card.GetSector(0);
sector0.Access.DataAreas[0].Read = DataAreaAccessCondition.ConditionEnum.KeyAOrB;
sector0.Access.DataAreas[0].Write = DataAreaAccessCondition.ConditionEnum.KeyB;
sector0.Access.DataAreas[0].Increment = DataAreaAccessCondition.ConditionEnum.Never;
sector0.Access.DataAreas[0].Decrement = DataAreaAccessCondition.ConditionEnum.Never;

sector0.FlushTrailer("A0A1A2A3A4A5", "111111111111");

MAD and MAD2 Managements

To manage MAD and MAD2, the MiFARECard class implements two methods:

  1. GetSectors(int appId): This method returns a list of the sectors that are currently in use by the given application.
  2. AddAppId(int appId): This method insert reserves a sector to the given application and returns the number of the sector reserved.

    For example, the source code for an application that wants to reserve the use of a sector according to MAD specifications should look like this:

    MiFARECard card = new MiFARECard();
    int[] sectors = card.GetSectors(0x5210);
    int appSector;
    If ((sectors != null) && (sectors.Length > 0))
    	appSector = sectors[0];
    	appSector = card.AddAppId(0x5210);
    If (appSector == -1)
    		Throw new NoSectorsAvailableException();
    // get data from reserved sector
    Sector s = card.GetSector(appSector);


  • 5th January, 2011: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Sweden Sweden
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionReference missing Pin
Member 1248775126-Apr-16 23:08
memberMember 1248775126-Apr-16 23:08 
Questionmissing dll's Pin
serkanorhon31-Mar-16 4:57
memberserkanorhon31-Mar-16 4:57 
QuestionFor all those who are looking for missing dlls Pin
Wahab Hussain20-Jul-14 20:10
memberWahab Hussain20-Jul-14 20:10 
BugBug fix in AccessBits.cs Pin
nschmid4-Nov-13 3:15
membernschmid4-Nov-13 3:15 
QuestionSmall Bug in Access Bits Pin
nschmid4-Nov-13 3:08
membernschmid4-Nov-13 3:08 
GeneralMy vote of 1 Pin
Member 102593727-Sep-13 12:34
memberMember 102593727-Sep-13 12:34 
QuestionDDL mising Pin
julioglez8821-Aug-12 8:33
memberjulioglez8821-Aug-12 8:33 
QuestionWhere is DLL file? Pin
nowirch27-Mar-12 18:45
membernowirch27-Mar-12 18:45 
QuestionIt`s about Setting permmissions Pin
amraa16-Feb-12 20:16
memberamraa16-Feb-12 20:16 
SuggestionMissing HexEncoding Pin
Giorgio Bernardi24-Jan-12 6:08
memberGiorgio Bernardi24-Jan-12 6:08 
GeneralMy vote of 5 Pin
Mark Hesketh18-Jan-12 10:51
memberMark Hesketh18-Jan-12 10:51 
QuestionYear has passed, Pin
Monochromatique29-Dec-11 11:38
memberMonochromatique29-Dec-11 11:38 
Questiondahhh Pin
SaeedRaimi23-Oct-11 15:29
memberSaeedRaimi23-Oct-11 15:29 
Question[My vote of 1] dahhh Pin
SaeedRaimi23-Oct-11 15:28
memberSaeedRaimi23-Oct-11 15:28 
QuestionMissing references Pin
Member 238440830-Aug-11 22:57
memberMember 238440830-Aug-11 22:57 
QuestionNo referens Pin
bigmar1-Jul-11 8:39
memberbigmar1-Jul-11 8:39 
GeneralMissing references.. Pin
Member 778739826-Mar-11 14:03
memberMember 778739826-Mar-11 14:03 
GeneralMissing References Pin
anu200017-Jan-11 0:38
memberanu200017-Jan-11 0:38 
GeneralReferences Pin
marcos_sis10-Jan-11 2:31
membermarcos_sis10-Jan-11 2:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170117.1 | Last Updated 8 Jan 2011
Article Copyright 2011 by amgalbu
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid