Nesse artigo demonstrarei o quanto e simples acessar Smart Cards utilizando o Java SE.O material necessario:Cartao Java Card de Desenvolvimento.Leitor/Gravador padrao PC/SC ISO7816.IDE Netbeans / Eclipse.Ter completado com sucesso os 3 Artigos Hello World Java Card. Como ja havia dito tenho uma preferencia pelo IDE Netbeans, mas voce podera utilizar tranquilamente o Eclipse se desejar.Sem muitos rodeios vamos ao que interessa o Codigo:import java.util.List;import javax.smartcardio.*;public class SmartCardTest { /** * @param args */ public static void main(String[] args) { //"Fabrica" de Terminais PC/SC TerminalFactory factory; //Lista de Leitores PC/SC List terminals; //Terminal PC/SC CardTerminal terminal; //Smart Card Card card; //Smart Card ATR ATR cardATR; //Canal de Comunicacao com o Smart Card CardChannel cardChannel; //APDU de Comando CommandAPDU commandAPDU; //APDU de Resposta ResponseAPDU responseAPDU; //Buffer de Auxilio byte[] buffer; try { //Adquire Fabrica de Leitores factory = TerminalFactory.getDefault(); //Adquire Lista de Leitores PC/SC no Sistema terminals = factory.terminals().list(); System.out.println("Lista : " + terminals); //Adquire Primeiro Terminal da Lista terminal = (CardTerminal)terminals.get(0); System.out.println("Terminal Selecionado: " + terminal.getName()); //Estabelece Conexao com o Cartao na Leitora card = terminal.connect("*"); System.out.println("card: " + card); //Adquire ATR do Cartao cardATR = card.getATR(); buffer = cardATR.getBytes(); System.out.println("ATR : " + formatBuffer(buffer, buffer.length)); //Adquire Canal de Comunicacao cardChannel = card.getBasicChannel(); //AID do HelloWorld buffer = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00}; //Monta APDU de Envio commandAPDU = new CommandAPDU( 0x00, //CLA 0xA4, //INS - SELECT 0x04, //P1 0x00, //P2 buffer); //AID //Imprime Comando System.out.println("\n[SELECT COMMAND]"); System.out.println("=> " + formatBuffer( commandAPDU.getBytes(), commandAPDU.getBytes().length)); //Trasnmite e Recebe responseAPDU = cardChannel.transmit(commandAPDU); //Verifica Resposta if (responseAPDU.getSW() != 0x9000) { throw new Exception("Falha ao Selecionar : " + String.format("0x%04X", responseAPDU.getSW())); } //Imprime Resposta System.out.println("<= " + formatBuffer( responseAPDU.getBytes(), responseAPDU.getBytes().length)); //Bytes de Testes buffer = new byte[]{0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; //Monta APDU de Envio commandAPDU = new CommandAPDU( 0x00, //CLA 0x00, //INS 0x00, //P1 0x00, //P2 buffer); //Teste //Imprime Comando System.out.println("\n[TESTE BYTES]"); System.out.println("=> " + formatBuffer( commandAPDU.getBytes(), commandAPDU.getBytes().length)); //Trasnmite e Recebe responseAPDU = cardChannel.transmit(commandAPDU); //Verifica Resposta if (responseAPDU.getSW() != 0x9000) { throw new Exception("Falha ao Selecionar : " + String.format("0x%04X", responseAPDU.getSW())); } //Imprime Resposta System.out.println("<= " + formatBuffer( responseAPDU.getBytes(), responseAPDU.getBytes().length)); } catch (Exception e) { e.printStackTrace(System.out); } } /** * Converte Buffer bytes para String * @param buffer * @param length * @return String */ public static String formatBuffer(byte[] buffer,int length) { StringBuilder strBuff = new StringBuilder(""); for (int i = 0; i < length; i++) { strBuff.append(String.format("%02X", buffer[i])); } return strBuff.toString(); }}O Resultado ao executar deve ser similar a isso:Lista : [PC/SC terminal ACS ACR38U 0]Terminal Selecionado: ACS ACR38U 0card: PC/SC card in ACS ACR38U 0, protocol T=1, state OKATR : 3BF81300008131FE454A434F5076323431B7[SELECT COMMAND]=> 00A404000B0102030405060708090000<= 9000[TESTE BYTES]=> 00000000060A0B0C0D0E0F<= 00000000060A0B0C0D0E0F9000Vamos a analise do codigo: A partir do Java 6, a Sun disponibilizou uma API intitulada "Java Smart Card I/O" que tem como finalidade prover acesso a Smart Cards.Na linha 11 criamos uma variavel factory que instancia um objeto TerminalFactory, esse objeto implementa uma pilha de leitores que pode variar conforme a implementacao, no nosso caso usaremos o padrao getDefault() que implementa leitores PC/SC, lembrem-se existem diversos leitores com diversos tipos