title: Mifare Classic Authentication failure on some devices until the tag has been read with the Mifare Classic Tool
body: <p>I'm trying to read user data from sector 0 block 1 of Mifare Classic cards in a Xamarin Forms Android app. On most devices it works perfectly every time, but on a Unitech EA510 the authentication consistently fails UNLESS I first read the card using the Mifare Classic Tool (<a href="https://play.google.com/store/apps/details?id=de.syss.MifareClassicTool" rel="nofollow noreferrer">https://play.google.com/store/apps/details?id=de.syss.MifareClassicTool</a>). As soon as I've detected any tag with the Mifare Classic Tool my code works perfectly every time. I've checked the Mifare Classic Tool source code to see what else it's doing and borrowed the patchTag logic (it didn't help!).</p>
  <ol>
  <li>Scan tag with the app first time:
  <strong>Mifare Classic tag authentication failure: 8250A9B9</strong></li>
  <li>Scan tag using the Mifare Classic Tool</li>
  <li>Re-scan the tag with the app:
  <strong>Mifare Classic tag found: 8250A9B9 10240472</strong></li>
  <li>Scan another the tag with the app:
  <strong>Mifare Classic tag found: 8250A9C7 10395802</strong></li>
  </ol>
  <pre><code>public void OnTagDiscovered(Android.Nfc.Tag tag)
  {
      string tagId = string.Empty;
      string[] techList = tag.GetTechList();
      string sUid = string.Empty;
      if (Array.IndexOf(techList, &quot;android.nfc.tech.MifareClassic&quot;) &gt; -1) {
          MifareClassic mfc = null;
          try {
              sUid = BitConverter.ToString(tag.GetId()).Replace(&quot;-&quot;, &quot;&quot;);
              mfc = MifareClassic.Get(tag);
              mfc.Connect();
              bool bAuthenticated = false;
              if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyDefault.ToArray()))
                  bAuthenticated = true;
              else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyDefault.ToArray()))
                  bAuthenticated = true;
              else if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyMifareApplicationDirectory.ToArray()))
                  bAuthenticated = true;
              else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyMifareApplicationDirectory.ToArray()))
                  bAuthenticated = true;
              else if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyNfcForum.ToArray()))
                  bAuthenticated = true;
              else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyNfcForum.ToArray()))
                  bAuthenticated = true;
              if (bAuthenticated) {
                  int blockOffset = mfc.SectorToBlock(0);
                  byte[] block = mfc.ReadBlock(blockOffset + 1); // Sector 0/block 0 is the UID so go straight to block 1 for the payload
                  tagId = System.Text.Encoding.ASCII.GetString(block);
                  if (tagId.Length == 1 &amp;&amp; tagId[0] == 0x04)
                      // Ignore if ReadBlock returns a single byte 0x04, which appears to happen if there's a delay between the tag discovery and ReadBlock (e.g. running in the debugger) and we don't want to treat it as a conventional tag by acciden
                      tagId = string.Empty;
                  else if (tagId.Length &gt; 0 &amp;&amp; tagId.Contains('\0')) 
                      tagId = tagId.Substring(0, tagId.IndexOf('\0'));
              } else {
                  Console.WriteLine($&quot;Mifare Classic tag authentication failure: {sUid}&quot;);
              }
          }
          catch (Exception ex) {
              Console.WriteLine($&quot;Mifare Classic tag read exception: {ex.Message}&quot;);
          }
          finally {
              if (mfc != null &amp;&amp; mfc.IsConnected)
                  mfc.Close();
              if (tagId != string.Empty)
                  Console.WriteLine($&quot;Mifare Classic tag found: {sUid} {tagId}&quot;);
          }
      }
      if (tagId != string.Empty)
          Do stuff
  }
  
  </code></pre>