Poszukiwałem odpowiedniego rozwiązania problemu obsługi czytnika kart w C#, w przeciwieństwie niestety do Javy nie mamy do dyspozycji wbudowanej implementacji tego problemu. Na wielu angielskich stronach i blogach znalazłem jakieś kawałki kodu, nawet jakiś framework, ale niestety nic tak do końca nie chciało działać. W końcu z tego wszystkiego udało mi się uzyskać kawałek kodu, który zadziałał i może się komuś przyda. Zasada odczytu danych z karty jest dosyć prosta. Jedyne czego potrzebujemy to czytnik kart (oczywiście pod USB), kartę zbliżeniową bądź kontaktową oraz najważniejsze – specyfikację techniczną karty dzięki której poznamy komendy bitowe pozwalające na operacje na karcie.
Pierwszym krokiem jest dodanie do projektu biblioteki GemCard: klikamy prawym przyciskiem na projekcie, Add Reference…, wybieramy plik dll z dysku.
Następnie w klasie gdzie chcemy implementować bibliotekę dodajemy:
1: using GemCard;
Tworzymy obiekty potrzebne do obsługi czytnika i wydawania komend, dodajemy jeszcze stałe oznaczające odpowiedź zapytania. W naszym wypadku będą to stany prawidłowej odpowiedzi oraz “w trakcie”.
1: static APDUCommand apduSelectFileMF = new APDUCommand(0x00, 0xA4, 0x00, 0x0C, null, 0x02); 2: static APDUCommand apduReadRecord = new APDUCommand(0x00, 0xB0, 0xFF, 0xFF, null, 0xFF); 3: CardNative iCard = new CardNative(); 4: APDUParam apduParam = new APDUParam(); 5: APDUResponse apduResp; 6: const ushort SC_OK = 0x9000; 7: const byte SC_PENDING = 0x9F;
Kolejnym krokiem będzie napisanie kilku prostych metod:
1: ///2: /// Pobiera liste podlaczonych czytnikow oraz laczy sie z pierwszym na listy 3: /// 4: public void initReader() 5: { 6: string[] readers = iCard.ListReaders(); 7: iCard.Connect(readers[0], SHARE.Shared, PROTOCOL.T0orT1); 8: } 9: 10: ///11: /// Rozlacza czytnik kart 12: /// 13: public void disconnect() 14: { 15: iCard.Disconnect(DISCONNECT.Unpower); 16: iCard.StopCardEvents(); 17: }
Pozostaje już tylko napisanie odpowiednich metod wykonujących np. operację wyboru pliku lub odpytujących kartę o dane:
1: public void selectFile() 2: { 3: apduParam.Data = new byte[] { 0x3F, 0x00 }; 4: apduSelectFileMF.Update(apduParam); 5: apduResp = iCard.Transmit(apduSelectFileMF); 6: if (apduResp.Status != SC_OK && apduResp.SW1 != SC_PENDING) 7: throw new Exception(apduResp.ToString()); 8: } 9: 10: public byte[] readRecord() 11: { 12: apduParam.Reset(); 13: apduReadRecord.Update(apduParam); 14: apduResp = iCard.Transmit(apduReadRecord); 15: if (apduResp.Status != SC_OK) 16: throw new Exception(apduResp.ToString()); 17: 18: return apduResp.Data; 19: }
Gotowe! Wystarczy teraz tylko zabrać się za pisanie programów dających dostęp do komputera, systemów a może nawet pomieszczeń? Powodzenia.

7 stycznia 2010 o 07:00
Dopisz gdzieś w tytule o jakie karty Ci chodzi, bo \’czytnik kart\’ się domyślnie kojarzy z czytnikiem flasshowych kart pamięci :P
widzę, że nad czymś ciekawym siedzisz;)
7 stycznia 2010 o 07:51
Czytnik kart flashowych? Przecież to jest zwykła obsługa dysku – IOFile ;)
7 stycznia 2010 o 19:49
Ja wiem, że z treści wynika o co chodzi, ale z tytułu nie;)