Windows Developer
Der Artikel „Mit Karte, bitte!“ von Helmut Stoiber ist erstmalig erschienen im Windows Developer 7.2012
Programmierschnittstelle
Die Kommunikation zwischen einer Applikation und einer Chipkarte läuft unter den Windows-Betriebssystemen über das WinSCard-Modul. Als Programmierschnittstelle stellt dieses Modul das klassische C++ API in Form einer Header-Datei (WinSCard.h) und einer Bibliothek (WinSCard.lib). bereit. Alternativ kann für die Programmierung mit C# oder Visual Basic auf eine DLL namens WinSCard.dll zurückgegriffen werden. Hierbei handelt es sich um eine traditionelle Windows-DLL und nicht um ein .NET-Assembly, sodass zunächst ein Wrapper implementiert werden muss. Die Definition der von dem WinSCard-Modul bereitgestellten Funktionen und deren Signaturen kann dem Header WinSCard.h entnommen werden.
Listing 1 zeigt exemplarisch das Wrappen der WinScard-Funktion SCardConnectA. Zunächst ist die entsprechende Funktionsdeklaration in WinSCard.h zu lokalisieren und die Parameterliste zu analysieren. Die Funktionen in WinSCard.h sind alle nach demselben Schema aufgebaut: Der Rückgabewert der Funktion ist stets vom Typ LONG, wobei die Null (0) eine fehlerfreie Ausführung der Funktion ausweist. Die Übergabe und Rückgabe von Parametern erfolgt in Form einer Parameterliste. Bei der Implementierung des Wrappers müssen sämtliche C++-Datentypen mit adäquaten C#-Typen substituiert werden. Da es sich bei C++-Typen primär um Pointer und/oder Strukturen handelt, ergibt sich die Problematik einen geeigneten C#-Datentyp zu finden oder eine selbstdefinierte Struktur einzusetzen. In Listing 1 werden im Rahmen der C#-Funktionsdeklaration neben Standardtypen auch Pointer und Referenzen verwendet. Die übrigen Deklarationen, die für eine vollständige Kommunikation mit einem Chipkarteninterface benötigt werden, können dem Quelltext des Demoprojekts entnommen werden.
Listing 1: C#-Wrapper
// Definition aus WinSCard.h extern WINSCARDAPI LONG WINAPI SCardConnectA( __in SCARDCONTEXT hContext, __in LPCSTR szReader, __in DWORD dwShareMode, __in DWORD dwPreferredProtocols, __out LPSCARDHANDLE phCard, __out LPDWORD pdwActiveProtocol); // C#-Wrapper using System.Runtime.InteropServices; [DllImport("winscard.dll", CharSet = CharSet.Auto)] internal static extern uint SCardConnect( IntPtr context, string szReader, uint dwShareMode, uint dwPreferredProtocols, ref IntPtr phCard, ref uint pdwActiveProtocol);
Die benötigte Header-Datei (WinSCard.h) und die Bibliothek (WinSCard.lib) sind Bestandteil des Microsoft SDKs und sind nach einer Standardinstallation unter. Program FilesMicrosoft SDKsWindowsv7.1Include beziehungsweise Lib gespeichert. Die für den Wrapper benötigte DLL (WinSCard.dll) ist in der Regel unter WindowsSystem32 zu finden.
Smart-Card-Demo
Diese Smart-Card-Demo stellt die komplette Funktionalität und eine vollständige Schnittstelle für die Kommunikation und den Datentransfer zwischen einer PC-Anwendung und einer Chipkarte bereit. Als Entwicklungsumgebung für die C#-Implementierung findet Visual Studio 2010 Verwendung, sodass daraus ein .NET-Standardprojekt (Solution) SCDemo.sln resultiert, das als komplettes ZIP-Archiv SCDemo.zip auf der Heft-CD vorliegt. Das Projekt setzt sich primär aus den drei nachfolgend näher beschriebenen Klassen SCManager.cs, WinScardWrapper.cs und SCDemo.cs zusammen.
Die Klasse SCManager.cs enthält die in Tabelle 8 aufgeführten C#-Funktionen, die direkt mit den C++-Funktionen der WinScard.dll korreliert sind. Der Name jeder C#-Funktion ist von dem jeweiligen in der WinScard.dll definierten Funktionsnamen abgeleitet, in dem das Prefix SCard weggelassen ist. Demzufolge wird beispielsweise aus SCardEstablishContext (WinScard.dll) der C#-Funktionsname EstablishContext.
Die C#-Funktionen enthalten neben dem eigentlichen Aufruf der von WinScardWrapper.cs bereitgestellten Funktionen zusätzliche Codesequenzen, die zum Beispiel die zu übergebenden oder die zurückgelieferten Funktionsparameter aufbereiten. Weiterhin sind Abfragen enthalten, die sicherstellen, dass ein gültiges Context Handle existiert, bevor eine Funktion aufgerufen wird, die dieses Handle benötigt. Damit ist sichergestellt, dass die Klasse SCManager.cs in Verbindung mit der Klasse WinScardWrapper.cs universell und komfortabel für beliebige .NET-Chipkartenapplikationen eingesetzt werden kann, indem die in Tabelle 8 aufgeführten C#-Funktionen verwendet werden.
Tabelle 8: C#-Funktionen der Smart-Card-Demo
C#-Funktion | Kurzbeschreibung |
---|---|
EstablishContext | Liefert eine Referenz auf ein Context Handle |
ReleaseContext | Freigabe eines Context Handle |
GetReaderGroups | Liefert einen String Buffer, der alle verfügbaren Lesergruppennamen durch ein NULL-Zeichen separiert enthält |
GetReaders | Liefert einen String Buffer, der alle verfügbaren Lesernamen durch ein NULL-Zeichen separiert enthält |
GetCards | Liefert einen String Buffer, der alle verfügbaren Kartennamen durch ein NULL-Zeichen separiert enthält |
GetStatusChange | Liefert Statusinformationen zu den übergebenen Lesern |
CardConnect | Verbindungsaufbau zu einer namentlich übergebenen Karte |
CardDisconnect | Verbindungsabbau zu einer namentlich übergebenen Karte |
CardStatus | Liefert Informationen bezüglich Protokoll und Karte |
CardTransmit | Senden von Command-APDU und Empfangen von Response-APDU |
Der Code der Klasse WinScardWrapper.cs ist in die beiden Regionen WinScard.h – Definitionen und WinScard.dll – Imports aufgeteilt. Erstgenannte Region enthält aus der genannten Header-Datei übernommene und an C# angepasste Konstantendeklarationen. In der zweiten Region finden sich die aus WinScard.dll zu importierenden Funktionsaufrufe, die, wie anhand von Listing 1 erläutert, implementiert werden. Die Klasse SCDemo.cs stellt ein einfaches grafisches Interface (GUI) gemäß Abbildung 10 bereit, wobei die in Tabelle 9 beschriebenen Funktionen verfügbar sind und die Kommunikation zwischen einer .NET-Applikation und einer Kombination aus Reader und Chipkarte unterstützen.

Im Beispiel gemäß Abbildung 10 wird die APDU-Sequenz 0084000008 zur Chipkarte gesendet. Dies entspricht dem Chipkartenkommando Get Challenge. Unabhängig von dem geforderten Security-Level antwortet eine Smart Card immer auf dieses Kommando, da der von Get Challenge zurückgegebene Wert (Zufallszahl) in jedem Fall für den Aufbau eines erhöhten Sicherheitslevel erforderlich ist.
Tabelle 9: Funktionalität von SCDemo
SCDemo-Button | Kurzbeschreibung |
---|---|
List Groups | Liefert eine Auflistung der im System bekannten Lesergruppen |
List Reader | Ermittelt die im System bekannten Leser und stellt sie zur Auswahl in das Kombinationsfeld „Reader Name“ |
List Cards | Liefert eine Auflistung aller in der „Smart Card Database“ des Systems bekannten Karten, wobei entweder ein ATR String oder ein globaler Interface-Identifier zu übergeben ist |
Get ATR | Liefert den ATR für alle aktiven Leser |
Get Card Status | Liefert Informationen zu Protokoll und Karte |
Send APDU | APDU aus der gleichnamigen Textbox senden und das Resultat in der Ausgabe-Textbox darstellen |
Clear | Inhalt der Ausgabe-Textbox löschen |
Scan File | Ermittlung gültiger File Identifier (FID) |
Close | SCDemo schließen |
Ausblick
Nachdem in diesem ersten Teil des Artikels unter anderem Grundlagen, Standards und Chipkartenkommandos sowie die Programmierschnittstelle vorgestellt wurden, beschäftigt sich der zweite Teil mit den gebräuchlichsten Chipkarten und zwar unter dem Aspekt der Anwendungsmöglichkeiten (Applikationen). Beginnend mit der Analyse einer unbekannten Chipkarte mithilfe der im ersten Teil vorgestellten SCDemo-Applikation werden die Funktionalität sowie die zugehörigen Applikationen für HBCI-Karten, Kryptografiekarten, SIM-Karten bis hin zu EC-Karten (Geldkarten) vorgestellt.