Smart Cards durch die in Java eingebaute Java Smartcard I/O javax.smartcardio.* ansprechen

Zuerst mache ich eine kleine Einführung in das Thema Java und Smartcads und beschreibe danach wichtige Punkte für Linux und Windows.

Java hat seit Version 1.5 (5.0) eine Unterstützung für Smartcards bereits eingebaut. Es nutzt dafür die eigene Provider Technik und greift über PC/SC auf die Smartcard zu. Das bedeutet es sind keine weiteren Module für Java notwendig (früher JPCSC für Linux) und die Nutzung erfolgt unabhängig vom Betriebssystem. Zumindest kann ich das für Windows XP/Vista und Linux bestätigen. FreeBSD und Sun Solaris sollten genau so gut funktionieren. Weitere Informationen zu Betriebssystemen in den nächsten Absätzen.

Unter Windows ist die Verwendung denkbar einfach. Für die Nutzung ist ein installierter Treiber für das Lesegerät (Terminal) und natürlich Java notwendig. Windows bringt eine eigene PC/SC Implementierung mit, die Java über den eingebauten Provider nutzt. Dadurch ist die Installation und Einrichtung sehr einfach.

Für Linux ist die Installation fast genau so einfach. Durch die verschiedenen pcsclite-Versionen (PC/SC Implementierung unter Linux) sind aber die Header-Datei (.h) für die Bibliothek notwendig, damit Java die PC/SC Bibliothek richtig ansprechen kann. Dafür reicht meistens die Installation der folgenden Pakete:

  • libpcsclite1
  • pcscd
  • libccid
  • libpcsclite-dev  (WICHTIG: Hier sind die notwendigen Header-Dateien)

Fehlt das Paket libpcsclite-dev bzw. die Header Dateien, so kann Java die PC/SC Bibliothek nicht nutzen und findet deswegen kein Lesegerät (Terminal).

Für Debian/Ubuntu und weitere Debian-Derivate ist die Installation denkbar einfach:

[code]
sudo aptitude install libpcsclite1 pcscd libccid libpcsclite-dev
[/code]

Die Nutzung der JPCSC Middleware, welcher veraltet ist, habe ich bereits früher hier beschreiben.

Um die Verwendung der Java Smartcard I/O zu testen, habe ich ein paar kleine Testprogramme geschrieben, die ich hier veröffentliche. Sie sind auf Englisch kommentiert, so dass keine weitere Erklärungen erfolgen. Ich denke die paar Worte Englisch wird wohl jeder verstehen können. Sie sind extra kurz und einfach gehalten.

[code]
import java.util.List;
import javax.smartcardio.*;

/*
* Look in rt.jar for „javax.smartcardio“ to get further information
* Defined in: JSR 268
*/
public class ListSmartcardReaders {

public static int listCounted() {

/* we use the default TerminalFactory */
TerminalFactory factory = TerminalFactory.getDefault();

try {
/* We can have multiple terminals on one System, so we get a list */
List terminals = factory.terminals().list();

for (CardTerminal terminal : terminals) {
System.out.println(„Card_Terminal_Name: „+ terminal.getName());
System.out.println(„Card_in_Terminal_present: „+terminal.isCardPresent());
System.out.println(„——————————————–„);
}
return terminals.size();

} catch (CardException e) {
e.printStackTrace();
}
return 0;
}

public static void main(String[] args) {
listCounted();
}
}
[/code]

[code]
import java.util.List;
import javax.smartcardio.*;

/*
* Look in rt.jar for „javax.smartcardio“ to get further information
* Defined in: JSR 268
*/
public class ConnectReader {

/**
*
* @param index is the array index of the terminal list (0..x)
* @throws CardException if there are problems accessing the smartcard
*/
public static void connectCard(int index) throws CardException {

/* Is a Reader connected we can access? */
if (TerminalFactory.getDefault().terminals().list().size() == 0) {
System.err.println(„No reader present“);
return;
}

/* Terminal we are working on */
CardTerminal terminal = TerminalFactory.getDefault().terminals().list().get(index);

/* Is a card present? */
if (!terminal.isCardPresent()) {
System.err.println(„No Card present!“);
return;
}

/* Here you have to choose „T=0″,“T=1“, „T=2“, check documentation of your smart card */
//Mostly it’s „T=1“, for older cards its „T=0“
Card card = terminal.connect(„T=1“);

System.out.println(„Card_Info: „+card.toString());
System.out.println(„Card Protocol: „+ card.getProtocol());

//Reset the card for use
ATR atr = card.getATR();

System.out.println(„ATR: “ + atr.getBytes());
System.out.println(„ATR historical bytes: „+ atr.getHistoricalBytes());

/* Get the basic channel. This one can’t be closed */
CardChannel channel = card.getBasicChannel();

/* Try to send a command. This one won’t work! */
byte[] command = { 0, 0, 0, 0};

CommandAPDU someApdu = new CommandAPDU(command);

ResponseAPDU r = channel.transmit(someApdu);
/* Response encoded in bytes */
byte[] response = r.getBytes();

System.out.println(„response: „+ response);

card.disconnect(false);
}

public static void main(String[] args) {
try {
//First Terminal = 0
connectCard(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
[/code]

Für weitere Information über APDUs und die Nutzung der Smartcards empfehle ich das Lesen des Buches Handbuch der Chipkarten oder direkt die dazugehörigen ISO-Normen ISO-7816 und im Speziellen die ISO-Normen ISO7816-4, ISO7816-8 und ISO7816-9.

Auf die Frage „Kommt man ohne das Buch bzw. die Normen aus?“, muss ich leider mit „definitiv nein!“ beantworten, da die Informationen sehr komplex sind und schwer zu verstehen. Im Internet ist bis Heute fast gar nichts vorhanden.
Ich rate aber nach Diplom-, Master- und Bachelorarbeiten zu dem Thema zu suchen. Da gibt es bestimmt Auszüge aus den Normen, um wenigstens die Zusammehänge und die Anfänge zu verstehen.

38 Gedanken zu „Smart Cards durch die in Java eingebaute Java Smartcard I/O javax.smartcardio.* ansprechen

  1. Hi Konstantin,
    ich wollte eine Applikation schreiben die Daten von einer SmartCard liest und diese verarbeitet.
    Leider kann ich meinen Reader nicht ansprechen, sprich „no Terminals present“. Ich benutze einen Chpdrive extern 320 von TOWITOKO. Treiber sind natürlich installiert. Weisst du was man noch machen konnte? Die Reader Software erkennt den Reader und die Kartendaten werden angezeigt, nachdem ich eine Karte reinsteckt habe.

    Ich bin für jede Hilfe dankbar.
    Grüße
    Dave

  2. Hi Konstantin,
    ich habe dein Code ( ListSmartcardReaders ) getestet und was mir einfällt , ist das Eclipse anfängt zu meckern (Errors), weil es Access Restrictions in der RunTime library rt.jar gibt. Man kann es lösen in dem man in den Einstellungen die deprecated API auf Warning umstellt. Weisst du evtl. was es für restrictions sind ???

    Grüße Rafael

  3. Hallo Rafael,

    das habe ich bereits früher in einem Beitrag geschrieben:
    http://konstantin.filtschew.de/blog/2009/07/25/unter-eclipse-ueber-java-auf-zugriffsbeschraenkte-not-accessible-pakete-am-beispiel-von-javax-smartcardio-im-java-projekt-zugreifen/

    Ich habe mich nicht weiter mit Restrictions beschäftigt. Das Beispiel entspricht aber so dem Beispiel von den Javadocs. Das bedeutet das Beispiel von SUN hat auch das Problem.

    Wenn du heraus findest, warum die Meldung kommt, dann schreib es mir bitte. Wenn ich es finde, dann werde ich es noch ergänzen oder einen neuen Beitrag dazu schreiben.

    Danke, Konstantin

  4. Hallo Dave,

    der Kartenleser muss PC/SC unterstützen, da SUN bis jetzt nur einen PC/SC Provider für die Java Smartcard I/O geschrieben hat. Meines Wissens nach gibt es im Moment auch keine weiteren Provider.

    Schau bitte selber bei Google oder beim Hersteller, ob dein Kartenleser bzw. der Treiber PC/SC unterstützt. Vielleicht fehlt auch noch was oder es gibt noch ein extra PC/SC Modul.

    Wenn du noch Fragen hast, dann melde dich.

    Gruß, Konstantin

  5. Hi Konstantin,
    Vielen Dank fpr die Antwort, mein Reader unterstützt PC/SC und das ist ja im Windows ia integriert. Ich habe auch im dem Chipdrive Diagnostic Tool die Funktionalität überprüft. Alles sieht in ordnung aus.
    hier die Screenshots des diagnose Tools:
    – der ausführliche Test : http://www.imgbox.de/?img=d50146x201.jpg

    – die Einstellungen : http://www.imgbox.de/?img=d25899r201.jpg

    ausführung des Java Codes verursacht folgende Exceptions:

    javax.smartcardio.CardException: list() failed
    at sun.security.smartcardio.PCSCTerminals.list(Unknown Source)
    at javax.smartcardio.CardTerminals.list(Unknown Source)
    at smartcardtest.ListSmartcardReaders.listCounted(ListSmartcardReaders.java:21)
    at smartcardtest.ListSmartcardReaders.main(ListSmartcardReaders.java:37)
    Caused by: sun.security.smartcardio.PCSCException: SCARD_E_NO_READERS_AVAILABLE
    at sun.security.smartcardio.PCSC.SCardListReaders(Native Method)
    … 4 more

    Die treiberstruktur sieht laut Hersteller folgendermassen aus:
    http://www.imgbox.de/?img=b12119l201.jpg

    Ich bin für weitere Ideen und Tipps Dankbar
    Grüße
    Dave

  6. Hallo Dave,

    deaktiviere mal diesen PC/SC Resource Manager als Test.

    Ich glaube nicht, dass es an Java liegt. Hast du einen aktuellen JDK (1.6.X) bei dir installiert?

    Probier bitte den Kartenlesern an einem anderen PC, damit ein Problem am PC ausgeschlossen wird. Das Programm kannst du ja ohne Eclipse starten.

    Wenn es am anderen PC funktioniert, dann installiere JAVA und Treiber für den Kartenleser neu.

    Schau mal, ob es ein Firmware update für deinen Kartenleser gibt.

    Ansonsten finde ich auch selber gar nichts zu dem Thema in Google. Deswegen kann man fast davon ausgehen, dass es an dem einen PC liegt, an dem du das probierst.

    Melde dich, falls du noch eine Frage hast. Schreib vielleicht auch den Hersteller an. Vielleicht brauchst du ein Firmware Update oder das Problem ist dem Support bekannt.

    Gruß, Konstantin

  7. Hi Konstantin,

    ich habe die Einstellung vorgenommen mit dem Ergebnis, dass es keine Excepton mehr gegeben hat dennoch ist der Reader nicht erkannt worden,

    factory.terminals().list().size() liefert 0 obwohl man ihn in dem Gerätemanager sieht. Ich hatte jdk 1.6.0_13-b03 installiert gehabt, nun habe ich auch mit der 1.6.0_17-b01 compiliert und ausgeführt . Es hat sich nichts geändert.

    Da ich nur ein Notebook zu Hause habe, werde ich es bei meinem Brüder versuchen müssen. Ich hoffe dass ich noch diese Woche weiter berichten kann.

    Auf jeden Fall funktioniert der Reader unter WinXP mit der mitgelieferten Software unter WIn7 bekam ich einen Bluescreen nachdem ich den Treiber installiert habe. Der Hersteller hat noch keine Treiber für Win7 und soweit ich mtbekommen gibt es auch keinen für Vista erst ab einer neueren Reader-Version.

    Falls ich es zum Laufen bekomme, werde ich hier berichten.

    Vielen Dank soweit

    Grüße Dave

  8. Hi Konstantin,

    ich habe es auf dem Rechner von meinem Brüder ausprobiert, leider ohne Erfolg.

    factory.terminals().list().size() liefert 0

    ich werde es mit einem anderen Reader versuchen müssen. :/

    Danke für bisherige Hilfe
    Grüße
    Dave

  9. Hi Konstantin,

    ich habe bis jetzt noch keinen anderen reader besorgt, und wollte es dennoch mit dem alten versuchen. Es gibt ja noch die CTAPI – bist du damit evtl. konfrontiert worden ?

  10. Hallo Dave,

    nein mit der CTAPI habe ich bis jetzt nichts gemacht. Sie ist nur im deutschsprachigem Raum verbreitet und gilt als „veraltet“.
    PC/SC ist im Moment der Standard für Smartcard Communication und wird es vermutlich noch eine Zeit lang bleiben.

    Siemens stellt zwar sehr gerne für ihre Smart Cards eigene Bibliotheken und APIs zur Verfügung, damit die Leute mit APDUs nicht an deren Karten rumspielen, aber das ist Firmenpolitik und ich finde es kontraproduktiv. Der Kram läuft natürlich nur unter Windows.

    Ich weiß im Moment nicht so wirklich, wie ich dir helfen kann. Hast du beim Hersteller angefragt? Eigentlich ist der Hersteller für so Probleme zuständig. Versuche einfach mal dein Glück.

    Falls du einen neuen Kartenleser suchst, so kann ich dir Omnikey empfehlen, weil die Entwicklung und der Support in Deutschland sitzt. Sie sind sehr kompetent und reagieren auch bei Anfragen bezüglich Linux und neuen Karten.

    Ansonsten sind die Lesegeräte von SCM Electronics auch sehr gut. Den Support von SCM habe ich nicht getestet, da der Reader so ohne Probleme mit allen Karten funktioniert hat.

    Falls du dir ein neues Lesegerät zulegst, nimm dir am besten einen mit RFID Schnittstelle. Bald haben wir alle ganz viele funkende Karten neben dem elektronischen Reisepass.

    Folgende Lesegeräte kann ich empfehlen (bei E-Bay teils sehr günstig):
    SCM Microelectronics SDI010
    Omnikey Cardman 5321

    Gruß, Konstantin

  11. Hi Konstantin,

    bei mir hat sich momentan nichts getan. Ich habe ledigliech erfahren das ich für mein Vorhaben gezwungen bin die CTAPI zu benutzen – denn wer Anwendungen entwickelt, die die Daten von den Krankenkarten auslesen, muss die CTAPI benutzen denn nur diese ist dazu zugelassen. Ich werde also weiter recherschieren müssen, um den Wrapper zu finden und zu integrieren.

    Danke für die Tipps
    werde mir das Gerät anschauen müssen.

    Grüße
    Dave

  12. KVK-Karten? Das sind Memory-Karten, die vom PCSC-Standard nicht unterstützt werden. PCSC kann meines Wissens nur was mit Prozessorkarten anfangen. es gibt in der PCSC-Implementierung unter Windows zwar auch einen (sehr dünnen) Layer, um Memory_Karten mittels (Peudo-APDUs) anzusprechen, meines Wissens nach funzt das aber selten bis gar nicht.
    Unter PCSC gibt es kein ReadMemory oder WriteMemory, PCSC funktioniert mit APDUs (T=0 oder T=1), aber Speicherkarten (wie die KVK) können APDUs nicht interpretieren (haben ja keinen Prozessor).
    Gruss Peter

  13. Hallo,

    ListSmartcardReaders funktioniert bei mir,
    Card_Terminal_Name: OMNIKEY CardMan 5×21 0
    Card_in_Terminal_present: true

    Auch die andere Anwendung geht:
    Card_Info: PC/SC card in OMNIKEY CardMan 5×21 0, protocol T=0, state OK
    Card Protocol: T=0
    ATR: [B@5afd29
    ATR historical bytes: [B@1a2961b
    response: [B@15dfd77

    Musste nur das Protokoll für die Karte ändern auf T=0.
    Wollte mich hiermit nur mal bedanken, da ich es für mein Studium brauche !

    Kartenleser von OMNIKEY
    Karte : von wrankl.de (lag dem buch als Testeksemplar bei)
    mfg
    Chris

  14. Hi Konstantin,
    ich arbeite gerade an der Kommunikation mit einer Karte über PC/SC und habe ein Problem: lt. Spezifikation der Karte muss APDU nach ISO 7816-4 aufgebaut sein, mit dem Vermerk, dass LE Byte immer vorhanden sein muss, auch wenn es 0x00 ist. Wenn ich APDU aufbaue z.B.: 90 5A 00 00 03 01 00 00 /*LE*/ 00 und diese über CardChannel – Funktion transmit sende, dann wird dieser LE-Byte abgeschnitten und ich bekomme zurück 91 + „invalid telegram“.

    Ähnliches Verhalten habe ich auch bei jpcsc festgetstellt. LE Byte wird immer abgeschnitten.

    Zusätzlich, wenn ich die Daten mit der Funktion transmit(ByteBuffer arg0, ByteBuffer arg1) sende, also 5A 01 00 00, dann wird die Telegramm geändert und stattdessen 18 01 00 00 geschickt. Als ob es ein Überlauf bei 0x40 statt findet. Ist es ein Bug oder habe ich was nicht beachtet?

    Ich werde froh sein, wenn du mir paar Tipps geben kannst. Danke.

    Gruß, Oleg

  15. Hallo Oleg,

    normalerweise wird nichts abgeschnitten oder verändert. Wie kommst du drauf, dass es verändert wird? Hast du einen Sniffer an der USB/Com Schnittstelle laufen?

    Du hast bei deinem Befehl das Class Byte auf 90 gesetzt. Das bedeutet, du verwendest propriätere Befehle, die nicht in der ISO 7816-4 spezifiziert sind. Da kann ich dir schwer helfen, da ich nicht weiß, was die Befehle bedeuten oder was du vor hast.

    Einen Bug in dem Bereich kann ich mir schwer vorstellen. Verwendest du Java Smartcard I/O oder? Es kann noch sein, dass dein Treiber vom Lesegerät ein Problem hat. Das kann ich aber ohne Informationen nicht einschätzen.

    Melde dich, wenn du noch Fragen hast.

    Gruß, Konstantin

  16. Hi,

    T=0 Protokoll unterstützt LE Byte nicht, das wird erklären wieso LE Byte nicht mitgeschickt wurde. Es muss auf jedenfall bei neuen Karten, wenn LE mitgeschickt werden muss, auf T=1 gehen.

    Das mit dem 0x5A to 0x18 vermute ich, dass es an dem „speziellen“ Befehl liegt. Wenn ich es in den Wrapper Befehl packe (ist von der Karte vorgeschrieben), funktioniert alles wunderbar, auch wenn den Befehl direkt über „PCSC Test Applikation“ sende.

    Auf jedenfall hat Konstantin recht: Es ist kein Bug und es wird nix verändert. Die Definitionen sollen einhalten werden :), dann klappt vielleicht alles.

    Gruß, Oleg

  17. Ich empfehle, nochmals den Standard 7816-3 genauer zu lesen. Natürlich kann man bei T=0 mit LE arbeiten. Die sogenannten Case-2 und Case-4 Kommandos antworten dann allerdings mit 61 bb, was bedeutet, dass Antwortdaten anstehen, die anschließend mit dem Kommando Get Response abgeholt werden müssen. Kommt allerdings ein 91 bb zurück, so bedeutet dies, dass ein sogenanntes proaktives Kommando ansteht, das man mit einem Fetch-Kommando abholt.

    Gruß MadMax

  18. Hallo Andy,

    das hängt maßgeblich von der Smartcard ab. Das Vorgehen sollte aber ungefähr so sein:
    1. Datei einlesen
    2. Dateiinhalt hashen
    3. Hashwert an die Smartcard zum signieren schicken
    4. Smartcard liefert eine Signatur zurück

    Die APDU zum Signieren findet man in der Dokumentation der Smartcard.

  19. Hallo Konstantin,

    ich habe Dein Beispiel mal getestet und bin auf folgende Seltsamkeit gestoßen:

    System: Ubuntu 10.04
    Kartenleser: SCM Microsystems SCR3311 (USB)

    Wenn ich meinen PC frisch hochfahre, komme ich über das
    Card card = terminal.connect
    nicht hinaus, sondern bekomme ein
    javax.smartcardio.CardException: connect() failed

    Wenn ich im Ubuntu mit tail -f /var/log/messages nachschaue, steht folgendes da:
    pcscd: winscard.c:368:SCardConnect() Card Not Powered

    Jetzt das Seltsame:
    Wenn ich über das beim Treiber enthaltene Tool MCTest auf Kartenleser und Karte zugreife, dann komme ich auf die Karte drauf.
    Noch skurriler:
    Ich starte MCTest, verbinde mich auf die Karte, schieße mit STRG+C MCTest ab, und lasse dann Dein Beispiel laufen.
    Dann funktioniert auch das Java-Programm.

    Meine Frage also:
    Wie bekomme ich das hin, dass ein PowerUp ausgeführt wird,
    bevor ich das terminal.connect() ausführen darf, bzw. wie frage ich das ab?

  20. Hallo Marc,

    ich würde sniffen, was das andere Tool an die Smartcard übermittelt, damit es funktioniert. Es kann sein, dass irgend ein spezieller Aufruf vorher über den Treiber oder über pcscd durchgeführt wird.

    Das Sniffen geht am einfachsten, in dem man pcscd im Vordergrund „-f“ und im Debug Modus „-d“ ausführt. Der gesamte Befehl: pcscd -f -d

    Wenn MCTest aber vorbei am pcscd was an die Smartcard schickt, dann wirst du es so nicht mitkriegen.

    Was sagt das pcsctool?

    Gruß, Konstantin

  21. Hallo Konstantin,

    vom sniffen her waren die Ergebnisse nur bedingt zu gebrauchen.
    java:

    00405821 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONNECT received by client 6
    00000022 winscard.c:303:SCardConnect() Attempting Connect to SCR3311 Smart Card Reader (21121002201789) 00 00 using protocol: 1
    00000012 winscard.c:368:SCardConnect() Card Not Powered

    mctest:

    00000018 winscard.c:303:SCardConnect() Attempting Connect to SCR3311 Smart Card Reader (21121002201789) 00 00 using protocol: 3
    00000012 winscard.c:452:SCardConnect() Direct access: no protocol selected
    00000010 winscard.c:459:SCardConnect() hCard Identity: 15e6a
    00000131 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONTROL received by client 6
    00002928 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONTROL received by client 6
    00001994 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONTROL received by client 6
    00001995 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONTROL received by client 6
    00001999 winscard_msg_srv.c:317:SHMProcessEventsContext() command CONTROL received by client 6
    00001924 ifdwrapper.c:638:IFDControl() Card not transacted: 612
    00000011 ifdwrapper.c:640:IFDControl() ControlCode: 0x003136b0 BytesReturned: 773082880
    00000011 TxBuffer 86
    00000006 RxBuffer

    Zufällig habe ich aber gesehen, dass es das MCTest als Quelltext auf http://www.identive-infrastructure.com gibt.
    Ich habe das Tool dann Stück für Stück abgespeckt, bis nur noch die eine Routine übrig war, die den Unterschied ausmacht.

    Diese Funktion wird aufgerufen:
    MCardInitialize (hSCardContext, &pchReaders [anList [nReader]], &hMCardContext, &dwDllVersion);

    Was mache ich denn nun in Bezug auf Java (da bin ich noch nicht so fit) ?

    Gruß,
    Marc

  22. Hallo Marc,

    da wird anscheinend eine spezielle DLL eingebunden, die benötigt wird, um die Smartcard zu betreiben. Wie man das in Java löst, kann ich dir auf Anhieb nicht sagen. Frag mal den Hersteller der Karte, wie das unter Java gehen soll.

    Versuch vielleicht einfach danach in Google zu suchen.

    Gruß, Konstantin

  23. Hallo,
    kann ich mit javax.smartcardio nur die Daten eine SC lesen oder auch schreiben. Wo finde ich Beispiele?

    LG
    Michael

  24. Hallo Michael,

    wenn du wirklich was mit Smartcards machen willst, dann musst du dir wohl oder übel die ISO 7816-4 besorgen, da du ohne diese Dokumentation nicht weit kommst. Einfach so „schreiben“ ist nicht. Die Smartcard ist ein selbstständiger Rechner, mit dem du über Befehle kommunizierst. Informiere dich bitte besser darüber, bevor du so Fragen stellst.

    Gruß, Konstantin

  25. Hallo Konstantin,

    ich habe gerade angefangen ein Applet zu programmieren, um sich über eine Webseite mittels Smartcard authentifizieren zu können.
    Soweit funktioniert auch alles, nur habe ich ein ähnliches Problem wie der Dave im 6. Kommentar.
    Wenn kein Reader angeschlossen ist, dann bekomme ich die selbe CardException wie er bei list(). Mir fehlt also die Möglichkeit auf Abwesenheit von Readern zu prüfen.
    Getestet habe ich das Ganze mit dem Code aus deinem zweiten Beispiel.

    Du hast ihm damals gesagt, er solle den PC/SC Resource Manager deaktivieren. Wie war das gemeint, und ist der RM nicht genau dafür zuständig, Reader und Karten zu verwalten?

    Wenn dir nichts auch nichts einfällt, werde ich wohl die CardException abfangen.

    Wer sich auch für solche PC/SC Applets für Webseiten interessiert kann einen Blick auf diese Seite werfen:
    http://www.springcard.com/blog/2010/java-pcsc-accessing-smartcards-from-a-web-page/

    Ich bin übrigens auf Debian.

    Gruß, Peter.

  26. Hallo Peter,

    der Tipp mit dem Resource manager war da vermutlich falsch. Ich wollte nur sicher stellen, dass Dave alle unnötigen Programme zu macht, damit sie die Kommunikation mit dem Kartenleser/Smartcard einstellen. Sollte einer der Programme die Resource für sich beanspruchen, dann kann es passieren, dass kein weiteres Programm darauf zugreifen kann.

    Dein Problem ist meiner Meinung nach ein Problem der Treiberhersteller. Hast du ein anderes Kartenlesegerät probiert? Ich kann dir da nicht einfach so helfen, da ich ziemlich sicher dein Kartenlesegerät nicht habe. Meine Kartenlesegeräte haben keine solchen Probleme gehabt. Ich habe SCM und OMNIKEY Kartenleser verwendet.

    Ich habe unter Windows XP, Windows Vista, Ubuntu 8.04/10.04, Mac OSX 10.6 getestet und es hat funktioniert. Bei nicht Windows war die Installation der Treiber etwas aufwendiger, aber am Ende ging es immer.

    Gruß, Konstantin

  27. Hallo Konstantin,

    danke für deine Antwort.
    Ich habe mich wahrscheinlich nicht richtig ausgedrückt.
    Die Treiber sind schon lange drauf. Ich habe bereits Programme in C++ damit programmiert. Das Applet läuft ja auch wenn der Reader vor dem Programmstart eingesteckt ist.
    Nur eben, wenn kein Reader eingesteckt ist, wirft list() die Exception.
    Es ist übrigens ein Omnikey 5321 CR USB. Andere Reader habe ich nicht hier.

    Gruß, Peter.

  28. Hallo Peter,

    das macht zwar vom logischen her wenig Sinn, da eine Liste auch leer sein kann, aber das ist nun mal so. Siehe auch die Doku, da ist es beschrieben, dass eine CardException geworfen wird: http://docs.oracle.com/javase/6/docs/jre/api/security/smartcardio/spec/javax/smartcardio/CardTerminals.html

    Ich würde die Exception abfangen und den User darauf hinweisen. So hatte ich es damals auch gemacht. Ist etwas her, musste nachschauen.

    Ich hatte ganz am Anfang eine Menge Probleme mit Beta-Treibern, daher habe ich deine Frage zuerst mal falsch verstanden. Bei mir wurde mal der Kartenleser oder die Karte nicht erkannt. War ganz wir, bis eine stabile Version des Treibers erschienen ist.

    Gruß, Konstantin

  29. Hallo,
    ich will mich mit Smartcard beschäftigen und programmieren. Mit der Sprache Java und als IDE Eclipse.
    Welches Plugin für Eclipse könnt Ihr mir empfehlen?

    LG
    Michael

  30. Hallo Michael,

    für Smartcards gibt es meines Wissens nach kein Plugin für Eclipse. Würde auch wenig Sinn machen.

    Ich würde hier die ISO 7816-4, 7816-7 und 7816-8 als Plugin empfehlen.

    Beachte auch bitte den Unterschied zwischen „mit der Smartcard kommunizieren“ (Thema hier) und die Smartcard programmieren. Unter Smartcard programmieren verstehe ich Programme zu entwickeln, die auf der Smartcard selber laufen und mit denen man kommuniziert.

    Ansonsten wünsche ich dir viel Erfolg bei deinem Vorhaben. Du hast dir da kein leichtes Thema ausgesucht.

    Gruß, Konstantin

  31. Hm. Hübsche Anleitung. Unter Windows soweit kein Problem, Leser ist ein Reiner SCT cyberJack RFID komfort. Da funktioniert ConnectReader supi. Aber selbes getestet unter Debian tut überhaupt nicht. Ich habe auf nem Raspberry den Reader am laufen, zumindest zeigt mir pcsc_scan an, welche Karten stecken usw…aber ConnectReader liefert mir stur „no reader present“. Wo kann man denn noch suchen?

  32. Ich würde schauen, ob man auf das Lesegerät trotzdem zugreifen kann, wenn es auch heißt, dass kein Kartenleser oder keine Karte vorhanden ist. Ich hatte teilweise auch solche Probleme. Bei mir lag es an einer veralteten pcscd Version.

    Für Raspberry und Smartkarten hatte ich noch keine Zeit gehabt. 🙂

  33. Hallo Konstantin,

    vielen Dank für das Beispiel. Hat gleich funktioniert. Ich habe folgende Aufgabestellung: Ich möchte eine Zeichenkette (20 byte) auf die Karte schreiben und diese Zeichenkette wieder auslesen. Ist das überhaupt ohne weiteres Möglich oder muss gleich für die Karte ein Applet geschrieben werden.
    Für eine kurze Antwort würde ich mich sehr freuen.

    Mit besten Grüßen

    Ilia

  34. Hallo Ilia,

    ich kann dir hierzu keine direkte Antwort geben, weil es ganz verschiedene Smartcards gibt. Im Grunde sind die meisten Smartcards Minicomputer und haben oft eigene Befehlssätze bzw. Programme, mit den man ähnlich TCP/IP kommuniziert. Du musst also was über die Smartcard wissen, bevor du mit ihr kommunizieren kannst.

    Gruß, Konstantin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Die folgenden im Rahmen der DSGVO notwendigen Bedingungen müssen gelesen und akzeptiert werden:

Informationspflicht

Durch Abschicken des Formulares wird dein Name, E-Mail-Adresse und eingegebene Text in der Datenbank gespeichert. Für weitere Informationen wirf bitte einen Blick in die Datenschutzerklärung.