Saltar para o conteúdo

Java Card

Origem: Wikipédia, a enciclopédia livre.

Java Card é uma das menores plataformas Java, numa visão superficial, estaria enquadrada em J2ME, sendo focada em dispositivos, porém o foco de Java Card, ao contrário da primeira impressão que tive, não se limita aos cartões inteligentes, estendendo-se a outros dispositivos com limitações de processamento e armazenamento semelhantes, como o Java Ring. Costumo dizer que a Java Card está no âmbito de dispositivos ainda menores que os do âmbito J2ME.

Principais características

  • Interoperabilidade: “Escreva uma vez e rode em qualquer cartão inteligente que seja Java Card;
  • Seguro: Além do ambiente de execução seguro herdado de J2SE, Java Card implementa diversas funções criptográficas, aproveitando as funções dos cartões inteligentes como tokens criptográficos;
  • É Java! Aproveite seus conhecimentos J2SE para desenvolver para cartões inteligentes!
  • Capacidade de múltiplos aplicativos no mesmo cartão inteligente: imagine poder ter no mesmo cartão serviços dos correios, banco, telefonia, vale-refeição, etc. Este tipo de ambiente proposto pela plataforma Java Card oferece isso possibilitando inúmeras oportunidades de negócio;
  • Dinâmico: É possível instalar um novo applet que já foi distribuído. Imagine que se uma entidade precisar atualizar o serviço no cartão de seus clientes, não precisará mais enviar o mesmo novamente, na próxima vez que o cartão for inserido no terminal, a atualização será procedida;
  • Compatível com padrões da indústria: Toda o framework suporta a norma ISO 7816 que define diversos padrões sobre cartões inteligentes. Você tem celular GSM? Java Card suporta padrões relacionados a telecomunicações também de modo que hoje boa parte dos SIM Cards no Brasil são Java Cards.

Limitações

Uma das primeiras coisas que podemos pensar é como uma linguagem tão poderosa como Java pode executar num hardware tão limitado? Claro que se trata de uma versão enxuta de Java, o que conhecemos por subconjunto (subset) da linguagem. Veja abaixo a lista de recursos não suportados:

  • Carga dinâmica de classes
  • Security Manager
  • Finalization
  • Threads
  • Cloning
  • Controle de acesso nos pacotes
  • Keywords: native, synchronized, transient, volatile, strictfp
  • Classe: System

Processo de desenvolvimento

Primeiro você baixa o Sun Java Card Development Kit, prepara o ambiente (veja mais no nas referências no final do artigo) então você:

  1. Escreve o .java normalmente no seu editor preferido.
  2. Compila com javac
  3. Converte com a ferramenta Converter (Disponível no JCRE)
  4. Simula (opcional) com o JCWDE (Disponível no JCRE) ou C-JRE (Disponível no JCRE)
  5. Instala no cartão inteligente

Arquivo CAP

Em Java Card, o arquivo central não é o .class mas sim o .cap, resultado da conversão de um pacote de .class através da ferramenta Converter.

Java Card HelloWorld

Para finalizar, que tal um HelloWorld? Perceba que o exemplo usa valores hexadecial (bytes) para enviar uma mensagem APDU (veja mais sobre APDU) e que exitem métodos como select(), install(), deselect(), process() estes métodos estão relacionados ao ciclo de atividade e vida de um applet, (saiba mais sobre esses métodos).

Vamos lá:

/*

* Package:  br.com.igormedeiros

* Filename: HelloWorldJC.java

* Class:    HelloWorldJC

* Date:     08/05/2005 14:55:52

*

*/

package br.com.igormedeiros;

import javacard.framework.*;

/**

*

* Class HelloWorldJC

*

*/

public class HelloWorldJC extends javacard.framework.Applet {

// CLA Byte

final static byte HELLO_CLA = (byte) 0xB0;

// Verify PIN

final static byte INS_HELLO = (byte) 0x20;

public static void install(byte[] bArray, short bOffset, byte bLength) {

 (new HelloWorldJC()).register(

  bArray,

  (short) (bOffset + 1),

  bArray[bOffset]);

}

// processa o comando APDU

public void process(APDU apdu) {

 byte[] buffer = apdu.getBuffer();

 if ((buffer[ISO7816.OFFSET_CLA] == 0)

  && (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4)))

  return;

 // Validate the CLA byte

 if (buffer[ISO7816.OFFSET_CLA] != HELLO_CLA)

  ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);

 // Select the apropriate instruction (Byte INS)

 switch (buffer[ISO7816.OFFSET_INS]) {

  case INS_HELLO :

   getHello(apdu);

   return;

  default :

   ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);

 }

}

/**

 * @param apdu

 * @author Igor Medeiros

 * Get user id attribute

 */

private void getHello(APDU apdu) {

 // cadeia de bytes com a mensagem: "hello world Java Card"

 byte[] hello =

  {

   'h',

   'e',

   'l',

   'l',

   'o',

   ' ',

   'w',

   'o',

   'r',

   'l',

   'd',

   ' ',

   'J',

   'a',

   'v',

   'a',

   ' ',

   'C',

   'a',

   'r',

   'd' };

 // informa ao JCRE que será enviado uma resposta

 short le = apdu.setOutgoing();

 short totalBytes = (short) hello.length;

 // informa ao JCRE o tamanho da mensagem em bytes

 apdu.setOutgoingLength(totalBytes);

 // envia a mensgem para o host

 apdu.sendBytesLong(hello, (short) 0, (short) hello.length);

 }

}

Testando

Após enviar comando de select, envie o seguinte comando: B0 20 00 00

A saída será: 68 65 6C 6C 6F 20 77 6F 72 6C 64 20 4A 61 76 61 20 43 61 72 64 90 00

Ligações externas