domingo, 19 de dezembro de 2010

Hello World Java Card! (Parte 2 - Desenvolvendo e Testando Applets)

Chegou a hora de criarmos nossa primeira Aplicação e testa-la com o Simulador JCWDE.
Tenha certeza de ter configurado com sucesso o seu ambiente de desenvolvimento antes de começar, se ainda não o fez clique aqui.
Abra o Eclipse e vá no menu "File > New > Other..." e escolha "Java Card Project".


Pressione "Next" e digite "JCApplets" no campo "Project name" depois "Next" e "Finish".
Repita o processo novamente só que escolhendo "Java Card Applet".


Digite "jchelloworld" no campo "Package:" e "JCHelloWorld" no campo "Name" e pressione "Finish".


A imagem acima ilustra como deve ficar seu projeto ao final. Clique duas vezes e JCHelloWorld.java e realize as seguintes alterações no código conforme abaixo.
package jchellorworld;

import javacard.framework.*;

public class JCHelloWorld extends Applet {

 /** Buffer de Eco */
 private byte[] echoBytes;
 /** Tamanho Máximo do Buffer */
 private static final short LENGTH_ECHO_BYTES = 256;
 
 /**
  * Only this class's install method should 
  * create the applet object.
  */
 private JCHelloWorld() {
  //Inicia Buffer de Eco
  echoBytes = new byte[LENGTH_ECHO_BYTES];
  //Torna Selecionavel
  register();
 }

 /**
  * Installs this applet.
  * @param bArray the array containing installation parameters
  * @param bOffset the starting offset in bArray
  * @param bLength the length in bytes of the parameter data 
  *                in bArray
  */
 public static void install
    (byte bArray[], short bOffset, byte bLength)
    throws ISOException
 {
  //Apenas o Método Install pode criar o Applet 
  new JCHelloWorld();
 }

 /**
  * Processes an incoming APDU.
  * @see APDU
  * @param apdu the incoming APDU
  * @exception ISOException with the response bytes per 
  * ISO 7816-4
  */
 public void process(APDU apdu) throws ISOException {
  
  //Adquire Referencia do Buffer APDU
  byte buffer[] = apdu.getBuffer();
  //Adquire Quantidade de dados Recebidos
  short bytesRead = apdu.setIncomingAndReceive();
  //Quantidade a se Ecoar
  short echoOffset = (short)0;
  
  //Ao Selecionar boa prática retornar 0x9000
  if (selectingApplet())
   return;
  
  //Copia dado Recebido para buffer de eco
  while ( bytesRead > 0 ) {
   Util.arrayCopyNonAtomic(
        buffer,              //Fonte de Dados
        ISO7816.OFFSET_CDATA,//Ponto de Inicio
        echoBytes,           //Destino dos Dados
        echoOffset,          //Ponto de Inicio
        bytesRead);          //Quantidade a copiar
   //Desloca OffSet
   echoOffset += bytesRead;
   //Atualiza Quantidade Remanescente
   bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
  }
  
  //Informa JCRE que haverá dados de resposta
  apdu.setOutgoing();
  //Informa JCRE quantidade de dados
  apdu.setOutgoingLength( (short) (echoOffset + 5) );
  //Ecoa o Cabeçalho Recebido
  apdu.sendBytes( (short)0, (short) 5);
  //Ecoa os Dados recebidos
  apdu.sendBytesLong( echoBytes, (short) 0, echoOffset );
 }
}

Salve todo o Projeto.
O Código em questão é o exemplo que se recebe junto com o JCDK e pode ser encontrado em "C:\JCDK222\samples\src\com\sun\javacard\samples\HelloWorld\HelloWorld.java".
Agora vá no "Package Explorer" e selecione o arquivo "JCHelloWorld.java" e clique no menu "Java Card" e "Generate Script".


 Com isso 2 novos arquivos serão criados no "Package Explorer".


Esses arquivos contém os APDU's que usaremos para acessar o Applet enquanto ele estiver sendo simulado pelo JCWDE.
Para iniciar a simulação clique no menu "JCWDE > Debug" e pressione "OK".



Se tudo ocorreu bem seu Applet deve estar sendo executado conforme a figura abaixo.


Agora execute o "APDU Tool" que se encontra em "C:\JCDK222\bin\apdutool.bat".


Se chegou até aqui, parabéns pois configurou o ambiente todo corretamente e está pronto para desenvolver para qualquer Java Card disponíveis atualmente no mercado.
Agora abra os arquivos de Script "create-JCHelloWorld.script" e "select-JCHelloWorld.script" que o Eclipse criou para você nesses arquivos se encontram os APDU's para teste do seu Applet.

Vamos alimentar o cartão digitando o seguinte comando:
powerup;
Com isso você receberá em retorno o ATR do Simulador : "0x3B 0xF0 0x11 0x00 0xFF 0x00". 

Vamos selecionar o Card Manager do Simulador digitando o APDU : 
0x00 0xA4 0x04 0x00 0x09 0xa0 0x00 0x00 0x00 0x62 0x03 0x01 0x08 0x01 0x7F;
 Com isso você receberá em retorno o APDU enviado e o Famoso SW1=90 SW2=00 em resposta.

Vamos Instalar o Applet tornando-o Selecionavel, isso irá rodar o Método "install" do Applet, digite o APDU:
0x80 0xB8 0x00 0x00 0xd 0xb 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00 0x00 0x00 0x7F;
Em resposta você deverá receber o 9000 indicando tudo Ok.

Vamos enfim selecionar nosso Applet digitando o APDU :
0x00 0xA4 0x04 0x00 0xb 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00 0x00 0x7F;
Em resposta nosso Applet deverá retornar 9000. 


Nesse ponto nossa aplicação estará pronta para realizar o que programamos nela ou seja ecoar de volta qualquer dados que enviarmos a ela.
Então vamos enviar nossos dados para ela, como esse Applet é super simples ele não checa os Bytes CLA, INS, P1 e P2, ou seja a aplicação sempre ecoará o que receber no seguinte formato [CLA,INS,P1,P2] + [DATA se existir].
Vamos montar nosso primeiro APDU ISO-7816:

CLA = 0x00
INS = 0x00
P1 = 0x00
P2 = 0x00
Lc = 0x06 - Aqui indicamos que enviaremos 6 bytes de dados. 
DATA = 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
Le = 0x7F 

Logo digite no APDU Tool :
0x00 0x00 0x00 0x00 0x06 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x7F;
Em resposta teremos :
0x00 0x00 0x00 0x00 0x06 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x90 0x00;


Se tudo estiver conforme a figura acima, parabéns, você escreveu e testou um Applet Java Card com sucesso! E está pronto para testar os demais Applets que o JCDK traz como demonstração na pasta "Sample".
Uma breve explicação sobre o código fonte em questão, todos seus Applets extenderão "javacard.framework.Applet" e você deverá re-escrever dois métodos em especial "install" e "process" o método install é chamado pelo Card Manager do cartão assim que um comando de instalação (Global Platform) é invocado pelo Host. Lembrem-se no artigo sobre Global Platform havia explicado que o processo de instalação de uma aplicação no cartão compreendem em duas partes, carga (load) e instalação (install for install ou install for make selectable).
No método install você deverá instanciar seu Applet através do construtor, iniciar variáveis, alocar recursos e finalmente registrar seu Applet na lista de aplicações do cartão através do método "register", que pode ou não receber parametros no ato da instalação.
O método process é chamado sempre que o Host envia dados para o cartão, lembre-se  do comando ISO-7816 "select" que enviamos antes de enviar-mos nossa APDU para o cartão, ele informa ao JCRE para selecionar nosso Applet na lista de aplicações e a partir desse momento todos os APDU's seguintes serão enviados para nosso Applet através do método process.

Bom espero que esse artigo tenha sido esclarecedor para você, no próximo artigo estarei ensinando como fazer tudo isso utilizando um cartão físico real, para tanto será necessário um Java Card de Desenvolvimento e um Leitor de cartões de contato.

Um Grande Abraço e até a Próxima!

9 comentários:

  1. Cara, suas explicações são ótimas...
    Parabéns.. eu consegui fazer tudo

    ResponderExcluir
  2. Boa tarde, Ricardo.

    Tenho o Java (jdk1.6.0_37) e o JAVA CARD (Java Card 2.2.2) bem configurados conforme foi explicado na parte 1 deste tutorial, mas quando vou gerar o script aparece um erro.

    Java Card 2.2.2 Class File Converter, Version 1.3
    Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.

    error: jcpackage.AppletJC: unsupported class file format of version 51.0.

    conversion completed with 1 errors and 0 warnings.

    Sabes qual é o problema?

    Obrigado.

    ResponderExcluir
    Respostas
    1. Olá,

      Esse problema acontece porque você está executando com uma versão superior a 1.5, mude a versão do seu Java para 1.5 e deverá funcionar...

      Excluir
  3. qual software uso para gravar direto no chip do cartao ?

    ResponderExcluir
  4. Se for Gravar o Applet Java Card no cartão utilize o GPShell.

    ResponderExcluir
    Respostas
    1. Boa Tarde,

      Ricardo pra realizar a gravação com 1 leitor e gravador ACR38 no GPSHELL é necessario fazer todas essas configurações?

      Aguardo o contato
      caio_cantagallo@outlook.com

      Excluir
  5. Boa tarde Ricardo,
    Estou tendo um problema no momento de executar o "APDU Tool" que se encontra em "C:\JCDK222\bin\apdutool.bat". Ele não está abrindo e origina uma mensagem de erro:
    'C:\Program' is not recognized an internal or external command, operable program or batch file

    Outro passo anterior que falhou foi o momento de verificar
    %JC_HOME%\bin\verifycap -version
    que deu exatamente o mesmo erro.
    Você me pode dar uma ajuda? Obrigado

    ResponderExcluir
    Respostas
    1. Oi Ricardo,
      Consegui resolver o problema. Estava adicionando desnecessariamente na variável PATH o seguinte:
      %JC_HOME%\bin;
      %JAVA_HOME%\bin;
      %PATH%
      Removi, e configurei direitinho como você indicou e deu tudo certo.
      Obrigado

      Excluir

Observação: somente um membro deste blog pode postar um comentário.