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.