CSharpPCSC API (Wrapper) für .NET

Die .NET Framework-Klassenbibliothek unterstützt auch in der Version 4.0 keine Smartcards. Daher wurde im Rahmen dieses Buches ein CSharp PC/SC Wrapper entwickelt, welcher die wichtigsten Windows WinSCard-API Funktionen in der Klasse WinSCard einbettet. Zusätzlich zur WinSCard Klasse bietet die PCSCReader Klasse eine High-Level PC/SC API.

Low-Level-API
Die Klasse WinSCard aus dem Namensraum GS.SCard kapselt die am häufigsten benötigten WinSCard-API Funktionen in Form einer Klasse. Derzeit noch nicht implementierte WinSCard-API Funktionen kann man bei Bedarf in der quelloffenen Library einfach ergänzen. Alle Konstanten der WinSCard API aus der Headerdatei  winscard.h, sowie die Fehlercodes aus der Headerdatei  SCardErr.h sind in mehreren Enumerationen (Namensraum GS.SCard.Const und  GS.SCard.ReturnCodes) deklariert.

High-Level-API
Die Klasse  PCSCReader aus dem Namensraum  GS.PCSC verfügt über die Methoden Connect(), ActivateCard(), Exchange() und Disconnect(). Alle diese Methoden sind teilweise mehrfach überladen und ermöglichen auf einfache Art und Weise die Programmierung eines PC/SC kompatiblen Readers. 

icon_zip.gif CSharpPCSC API, Dokumentation und  Beispielprojekte


CSharp PC/SC Beispiele

Die C# Programmbeispiele kann man entweder mit Microsoft Visual Studio C# Express Edition, SharpDevelop oder auch mit Smart Card Magic.NET kompilieren und testen. Das Erstellen der Programme in Smart Card Magic.NET erfolgt in der gleichen Art und Weise wie in Kapitel 7.6.2 vorgestellt. Die im Kapitel 8 vorgestellten generischen Hilfsklassen CmdApdu, RespApdu, ByteArray, HexEncoding, HexFormatting, HexUtil, MifareClassicKeys, MifareClassicUtil, TripleDESCrypto und Rng werden in den folgenden Beispielen wieder verwendet.

icon_zip.gif PC/SC Reader Smart Card Magic.NET Script Examples

namespace GS.PCSCExample
{
  public class PCSCDESFireISO7816APDUs
  {
    static MainForm script;
    PCSCReader reader;
    
    public PCSCDESFireISO7816APDUs()
    {
      reader = new PCSCReader();
    }
    
    
    public static void Main(MainForm script, string[] args)
    {
      PCSCDESFireISO7816APDUs readerScript = new PCSCDESFireISO7816APDUs();
      PCSCDESFireISO7816APDUs.script = script;
      readerScript.Run();
    }        
    
    public void Run()
    {
      try
      {   
          reader.Connect();
        
          reader.ActivateCard();
            
          //----------------------------------------------------------------------
          //                       Select Master File
          //----------------------------------------------------------------------
          // CLA = 0x00, INS = 0xA4, P1 = 0x00, P2 = 0x00, Lc = 2 (data length),
          // Data = 0x3F 00, Le -
          byte[] selectMF = new byte[]{ 0x00, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };  
             
          script.TraceWriteLine("    Select Master File: FID = 0x3F 00");
          reader.Exchange( selectMF, 0x9000);

          //----------------------------------------------------------------------
          //                       Select Application
          //----------------------------------------------------------------------                
          CmdApdu selectApplication = new CmdApdu();
          selectApplication.CLA = 0x00;   
          selectApplication.INS = 0xA4;  
          selectApplication.P1 = 0x04;    
          selectApplication.P2 = 0x00;
          selectApplication.Data = new byte[] {0x11,0x22,0x33,0x44,
                                               0x55,0x66,0x77,0x88};
  
          script.TraceWriteLine(" Select Application: AID = 0x1122334455667788");
          reader.Exchange(selectApplication, 0x9000);

          //----------------------------------------------------------------------
          //                       Select File
          //----------------------------------------------------------------------  
          CmdApdu selectFile = new CmdApdu();
          selectApplication.CLA = 0x00;   
          selectApplication.INS = 0xA4;   
          selectApplication.P1 = 0x00;    
          selectApplication.P2 = 0x00;
          selectApplication.Data = HexEncoding.GetBytes("00 01");
  
          script.TraceWriteLine("    Select File: FID = 0x0001");
          reader.Exchange(selectApplication, 0x9000);

          //----------------------------------------------------------------------
          //                       Update Binary
          //----------------------------------------------------------------------  
          // CLA = 0x00, INS = 0xD6, P1 = 0x00, P2 = 0x00, Lc = 8 (data length), 
          // Data = 0x31 32 33 34 35 36 37 38, Le -
          script.TraceWriteLine("    Update Binary:");
          reader.Exchange("00 D6 00 00 # (31 32 33 34 35 36 37 38)", 0x9000);

          //----------------------------------------------------------------------
          //                       Update Binary
          //----------------------------------------------------------------------  
          // CLA = 0x00, INS = 0xD6, P1 = 0x00, P2 = 0x00, Lc = 11 (data length), 
          // data = 0x48 65 6C 6C 6F 20 57 6F 72 6C 64 , Le -
          script.TraceWriteLine("    Update Binary:");
          reader.Exchange("00 D6 00 08 # (\"Hello World\")", 0x9000);   

          //----------------------------------------------------------------------
          //                       Read Binary
          //----------------------------------------------------------------------  
          // CLA = 0x00, INS = 0xB0, P1 = 0x00, P2 = 0x00 (offset), Lc = -, 
          // data = - , Le = 0x00
          script.TraceWriteLine("    Read Binary:");
          RespApdu respApdu2 = reader.Exchange("00 B0 00 00 00", 0x9000);                

          //----------------------------------------------------------------------
          //                       Read Binary
          //---------------------------------------------------------------------- 
          // CLA = 0x00, INS = 0xB0, P1 = 0x00, P2 = 0x08 (offset), Lc = -, 
          // data = - , Le = 0x00                
          script.TraceWriteLine("    Read Binary:");
          RespApdu respApdu1 = reader.Exchange("00 B0 00 08 10");
        
          if(respApdu1.SW1SW2 == 0x9000 && respApdu1.ReaderStatus == 0x00)
          {
            string cardText = System.Text.Encoding.ASCII.GetString(respApdu1.Data);
            Console.WriteLine("Card Text: " + cardText);
          }

        }
        catch (WinSCardException ex)
        {
          Console.WriteLine( ex.WinSCardFunctionName + " Error 0x" + 
                             ex.Status.ToString( "X08" ) + ": " + ex.Message );
        }
        catch (Exception ex)
        {

            Console.WriteLine( ex.Message );
        }
        finally
        {
            reader.Disconnect();
        }
     }
  }
}