Yet mailing lists are full of members asking what framework to use and how to get started, and unfortunately the example is slightly broken. So here is one that is fixed and show the selection of the Card Manager application on most Java - GlobalPlatform card in use toady.
/**
*
* This example is from http://pierreheuze.blogspot.com/2008/09/getting-started-with-smartcardio.html
*
* Using the javax.smartcardio package, it shows:
* - How to select a terminal
* - Connect to the card using a particular protocol
* - Send Command APDU to the card and process Response APDU.
* The Command APDU selects the CardManager, on a Java - GlobalPlatform card.
* So you need such a card to try this example, but it is easy to adapt the APDU to try
* on another kind of card.
*
* Copyright Pierre Heuze (r)
*
* This example is provided WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, modify, and distribute it for non-commercial and commercial
* purposes, in all cases you must acknowledge the copyright and keep this disclaimer.
*
* This particular example has been successfully compiled and tested using
* Eclipse 3.3.2 and Java 1.6.0_06. It is based on:
* http://java.sun.com/javase/6/docs/jre/api/security/smartcardio/spec/javax/smartcardio/package-summary.html
* But that one doesn't compile and doesn't show a meaningful APDU exchange.
* You should also look at the GlobalPlatform card specification http://www.globalplatform.org
* Comments welcome.
*
*/
import javax.smartcardio.*;
import java.util.*;
/**
* @author PHeuze
*
*/
public class ExSmartCardIO {
/**
* Utility function that converts a byte array into an hexadecimal string.
* @param bytes
*/
public static String toString(byte[] bytes)
{
final String hexChars = "0123456789ABCDEF";
StringBuffer sbTmp = new StringBuffer();
char[] cTmp = new char[2];
for (int i = 0; i <>> 4) & 0x0F);
cTmp[1] = hexChars.charAt(bytes[i] & 0x0F);
sbTmp.append(cTmp);
}
return sbTmp.toString();
}
/**
* @param args
*/
public static void main(String[] args) {
try
{
// Show the list of available terminals
// On Windows see HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Calais\Readers
TerminalFactory factory = TerminalFactory.getDefault();
List
System.out.println("Terminals: " + terminals);
// Get the first terminal in the list
CardTerminal terminal = terminals.get(0);
// Establish a connection with the card using
// "T=0", "T=1", "T=CL" or "*"
Card card = terminal.connect("*");
System.out.println("Card: " + card);
// Get ATR
byte[] baATR = card.getATR().getBytes();
System.out.println("ATR: " + ExSmartCardIO.toString(baATR) );
// Select Card Manager
// - Establish channel to exchange APDU
// - Send SELECT Command APDU
// - Show Response APDU
CardChannel channel = card.getBasicChannel();
//SELECT Command
// See GlobalPlatform Card Specification (e.g. 2.2, section 11.9)
// CLA: 00
// INS: A4
// P1: 04 i.e. b3 is set to 1, means select by name
// P2: 00 i.e. first or only occurence
// Lc: 08 i.e. length of AID see below
// Data: A0 00 00 00 03 00 00 00
// AID of the card manager,
// in the future should change to A0 00 00 01 51 00 00
byte[] baCommandAPDU = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x08, (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00};
System.out.println("APDU >>>: " + ExSmartCardIO.toString(baCommandAPDU));
ResponseAPDU r = channel.transmit(new CommandAPDU(baCommandAPDU));
System.out.println("APDU <<<: " + ExSmartCardIO.toString(r.getBytes()));
// Disconnect
// true: reset the card after disconnecting card.
disconnect(true);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}