Java Card
Esta página ou se(c)ção precisa ser formatada para o padrão wiki. |
Introdução
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 Java Card no escopo de dispositivos ainda menores que os do escopo 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*
4. Simula (opcional) com o JCWDE* ou C-JRE*
5. Instala no cartão inteligente
- Disponível no JCRE
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á:
/*
* Autor: Igor Medeiros * www.igormedeiros.com.br * 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
Links referentes www.igormedeiros.com.br