MokaByte Numero  37  - Gennaio 2000 
 
JavaCard: tecnologia Java 
per le smart card
di 
Roberto Fabbrica
Cosa sono e come funzionano le smart card fatte in casa Java


Attualmente sono disponibili molti modelli di SmartCard per le applicazioni più disparate. La maggior parte di questi però sono incompatibili fra loro a causa delle diversità degli ambienti d’esecuzione di cui sono dotati. L’ambiente JavaCard permette di standardizzare l’ambiente d’esecuzione, e quindi permette la realizzazione d’applicazioni per SmartCard portabili.

Introduzione
Negli ultimi anni il numero di SmartCard utilizzate in Europa e nel Mondo è cresciuto a ritmi vertiginosi. Buona parte di questa crescita, almeno in Europa, è dovuta all’utilizzo di SmartCard per i telefoni cellulari. I campi d’impiego delle SmartCard sono comunque estremamente vasti. Si va, infatti, dalle carte di credito, quali quelle di VISA International, alle carte per la semplice raccolta punti a scopo promozionale, quali le carte del club “Fai da Te” Agip.
Se è vero che la tecnologia delle SmartCard ha ormai raggiunto un alto livello d’affidabilità, è comunque impossibile non notare la babele di metodologie di progetto e d’implementazioni attualmente disponibili. Questo dipende principalmente dalla mancanza di uno standard per l’ambiente d’esecuzione della SmartCard. In pratica, un’applicazione sviluppata per una certa SmartCard non può quasi mai essere utilizzata per un’altra SmartCard.
La miglior soluzione disponibile per la standardizzazione dell’ambiente d’esecuzione è l’ambiente JavaCard, proposto da SUN Microsystems, l’azienda che ha creato il linguaggio di programmazione Java. L’implementazione di quest’ambiente prevede l’inserimento di un interprete Java standardizzato sulla carta e la creazione di una serie di API Java per l’accesso alle risorse della carta. In questo modo, è possibile sviluppare servizi in grado di funzionare indifferentemente su qualsiasi carta. Questa soluzione ha anche un altro grande vantaggio: l’utilizzo del linguaggio Java, un linguaggio di alto livello ben conosciuto da una moltitudine di sviluppatori, utilizzabile proficuamente sia per la carta sia per l’applicazione esterna di controllo.
In questo articolo si analizzeranno le caratteristiche salienti della tecnologia JavaCard e si verificherà la sua competitività rispetto agli ambienti SmartCard.
 

La tecnologia JavaCard
Le JavaCard (così sono chiamate le Smartcard che integrano l’ambiente JavaCard) presentano una serie di caratteristiche peculiari che le rendono estremamente competitive rispetto alle SmartCard. Queste caratteristiche sono le seguenti:
 

  • Indipendenza dalla piattaforma: un’applicazione per JavaCard (definita tecnicamente JavaCard Applet), scritta rispettando le regole imposte dall’API JavaCard, può essere utilizzata senza modifiche su JavaCard fornite da costruttori diversi;
  • Supporto a più applicazioni: su una stessa JavaCard possono coesistere diverse applicazioni (JavaCard Applet) indipendenti fra loro e selezionabili singolarmente in fase di esecuzione; 
  • Caricamento di nuove applicazioni dopo la consegna: dopo che una JavaCard è stata consegnata all’utente finale è ancora possibile procedere al caricamento di nuove applicazioni attraverso gli stessi terminali addetti all’espletamento dei servizi, questo per soddisfare le nuove necessità espresse dall’utente;
  • Flessibilità: il linguaggio utilizzato per programmare le JavaCard è un subset del linguaggio Java, quindi la programmazione può sfruttare il paradigma della programmazione ad oggetti;
  • Compatibilità con gli standard delle SmartCard: le JavaCard sono compatibili con lo standard ISO 7816, lo standard più diffuso nel campo delle SmartCard.


Per comprendere a fondo le caratteristiche dell’ambiente JavaCard è necessario conoscere anche l’hardware su cui è implementato. Questo è composto essenzialmente dal pool delle memorie e dal processore. Il pool delle memorie è costituito generalmente da tre tipi diversi di memoria: memoria ROM, memoria EEPROM e memoria RAM. Di seguito sono forniti i dettagli relativi ad ognuno:
 

  • Memoria ROM: questo tipo di memoria, a sola lettura, è utilizzato per contenere tutto il codice che non richiede modifiche, cioè il sistema operativo della JavaCard e la parte standard del JCRE (Java Card Runtime Environment, l’infrastruttura che permette il funzionamento della JavaCard). La dimensione di questo tipo di memoria è di circa 32 KByte per buona parte delle JavaCard attualmente in commercio, mentre la dimensione minima richiesta è di 24 KByte;
  • Memoria EEPROM: questo tipo di memoria, riscrivibile elettronicamente, è utilizzato per contenere le estensioni del JCRE e le JavaCard Applet (applicazioni sviluppate esternamente e caricabili sulla JavaCard), nonché gli oggetti non temporanei creati durante l’esecuzione delle JavaCard Applet. La dimensione di questo tipo di memoria è di circa 16 KByte per buona parte delle JavaCard attualmente in commercio, dimensione che rappresenta anche il limite minimo;
  • Memoria RAM: questo tipo di memoria, denominato anche volatile, è utilizzato per contenere l’heap e lo stack necessari per l’esecuzione, quindi le variabili e gli oggetti temporanei creati durante l’esecuzione delle JavaCard Applet. La dimensione di questo tipo di memoria è di circa un KByte per buona parte delle JavaCard attualmente in commercio, mentre la dimensione minima richiesta è di 500 Byte.


I processori utilizzati dalle JavaCard in commercio sono innumerevoli: questi possono essere processori a otto, sedici o trentadue bit e possono funzionare con frequenze dell’ordine di qualche MHz. In effetti, non esiste né uno standard per quanto riguarda il processore della JavaCard, né una posizione di predominio di un produttore di processori rispetto agli altri.
E’ importante notare che le configurazioni hardware descritte precedentemente sono compatibili con la maggior parte delle SmartCard utilizzate attualmente. Questo implica che l’ambiente JavaCard potrebbe essere adottato sulla maggioranza degli hardware attualmente disponibili e, secondariamente, che le differenze introdotte dagli ambienti di esecuzione proprietari non trovano una giustificazione plausibile nella diversità degli hardware disponibili.
I componenti software presenti sulla JavaCard, in esecuzione sull’hardware appena descritto, sono quelli mostrati in figura 1. L’ambiente JavaCard è, in effetti, l’integrazione di tutti i componenti in figura, escluse le Applet, che costituiscono invece l’implementazione delle applicazioni disponibili sulla JavaCard.
 
 
 

Figura 1 – Organizzazione del software JavaCard

Di seguito è riportata una breve descrizione di ognuna delle componenti di figura 1:
 

  • Metodi Nativi: sono i metodi che forniscono le funzionalità di I/O, le funzionalità crittografiche e i servizi di allocazione della memoria;
  • JCVM (Java Card Virtual Machine): è l’entità che si occupa dell’interpretazione del bytecode JavaCard e che fornisce il supporto al linguaggio. Questa è in pratica un interprete del subset del linguaggio Java utilizzato in ambiente JavaCard;
  • Framework: è l’insieme delle classi che implementano l’API JavaCard e include sia i package standard sia le eventuali estensioni standard. Questo componente provvede infine alla distribuzione agli altri componenti dei comandi provenienti dall’esterno, alla gestione delle operazioni atomiche e all’installazione delle JavaCard Applet;
  • JavaCard API: si tratta dell’interfaccia utilizzata dalle JavaCard Applet per l’accesso al JCRE e ai Metodi Nativi. Questo componente fornisce quindi un insieme di classi che permette di accedere alle risorse standardizzate presenti sulla JavaCard: tutto ciò rappresenta un passo necessario alla realizzazione di un ambiente indipendente e permette, in pratica, di appianare le differenze a livello di hardware e firmware eventualmente esistenti;
  • JCRE (Java Card Runtime Environment): questo componente raggruppa al suo interno la JCVM, il Framework, i Metodi Nativi e l’API JavaCard. Questo è, in effetti, l’ambiente JavaCard che permette la portabilità del codice scritto per una JavaCard su un’altra JavaCard;
  • Estensioni Proprietarie: si tratta di classi aggiuntive definite dal costruttore della JavaCard, che possono essere utilizzate dalle JavaCard Applet. Appartengono a queste classi aggiuntive tutte quelle classi che forniscono accessi a certi tipi di funzionalità dedicate, relative a JavaCard per applicazioni particolari quali JavaCard che integrano al loro interno orologi a tempo reale, hardware dedicati per l’esecuzione di particolari operazioni aritmetiche o altro ancora. Non devono essere confuse con le estensioni standard del Framework, che sono invece definite come classi opzionali dall’API JavaCard;
  • JavaCard Applet: sono applicazioni scritte in un subset del linguaggio Java per essere eseguite su JavaCard. Queste applicazioni implementano, in pratica, tutte le funzionalità della JavaCard accessibili dall’esterno. L’applicazione esterna di controllo può selezionarle una alla volta, in maniera esclusiva, e richiedergli certi servizi, quali la memorizzazione o la restituzione di dati o l’esecuzione di operazioni.


Come accennato precedentemente, dalla figura 1 si può chiaramente desumere che il JCRE utilizza la JCVM (Java Card Virtual Machine), i Metodi Nativi e il Framework (notare che quest’ultimo componente contiene al suo interno la JavaCard API). Come si può inoltre vedere, le Estensioni Proprietarie sono esterne al JCRE, mentre le JavaCard Applet sono il componente software di più alto livello e devono appoggiarsi sul JCRE per funzionare.
Si noti che questo tipo di organizzazione permette di astrarre dall’hardware e dal firmware sottostante in maniera estremamente elegante, fornendo ad alto livello un ambiente di esecuzione indipendente dalla piattaforma ed estremamente flessibile. La divisione dei package che formano la JavaCard API in package obbligatori ed estensioni e la possibilità di inserire estensioni proprietarie, nonché la presenza di una virtual machine che permette la gestione degli oggetti, rispecchia bene l’organizzazione degli ambienti Java disponibili sui PC o sulle workstation, fornendo allo sviluppatore un ambiente simile a quelli utilizzati abitualmente. Il risultato ottenuto dai progettisti dell’ambiente JavaCard non può che definirsi di alto livello, soprattutto tenendo conto di quanto sono ridotte le risorse hardware disponibili.
A proposito della JCVM (Java Card Virtual Machine), è interessante notare che questo tipo di VM (Virtual Machine) ha funzionalità ridotte rispetto alla JVM (Java Virtual Machine) disponibili per i PC o le workstation. La JCVM è, in effetti, solo una porzione della JVM e non è in grado di eseguire il loading delle classi e la risoluzione dei riferimenti: lo scopo per cui è progettata è quello di eseguire il bytecode JavaCard e gestire gli oggetti. Per questo motivo i Converter (convertitori utilizzati per tradurre il bytecode Java compilato su PC o su workstation in un formato che ne permetta il caricamento su JavaCard) eseguono anche i compiti di loading delle classi e risoluzione dei riferimenti. Più precisamente abbiamo quindi che:

  • la parte di JVM integrata nel Converter esegue la maggior parte delle verifiche, delle preparazioni e delle ottimizzazioni fatte dalle JVM di PC o workstation a tempo di loading delle classi. Per questo motivo sulla JavaCard è proibito il loading dinamico delle classi a tempo di esecuzione;
  • la parte di JVM integrata nella JavaCard, cioè la JCVM, esegue il bytecode, gestisce gli oggetti, mantiene separate le JavaCard Applet e gestisce la condivisione esplicita di dati.
Questa organizzazione della JVM, con la separazione in due entità integrate in ambienti diversi, è mostrata dalla figura 2.
 
 
 
Figura 2 – Separazione della VM JavaCard su due ambienti

In altre parole, come si può vedere dalla figura 2, la VM (Virtual Machine) di una JavaCard viene, in effetti, distribuita nello spazio e nel tempo tramite due componenti separati: uno all’esterno della JavaCard, integrato nel Convertitore, e uno all’interno della JavaCard, nella JCVM integrata nel JCRE. Per ulteriori informazioni si consulti [Snm98] e [Snm97c].
Notare che la JCVM, a causa delle ridotte risorse disponibili, presenta altre importanti limitazioni rispetto alla JVM utilizzata su PC o workstation. Per esempio, in ambiente JavaCard non sono gestite le stringhe e altri tipi di dati, mentre il tipo di dato intero è solo opzionale. I dettagli relativi a queste limitazioni non saranno descritti in questa sede per due motivi: in primo luogo questo articolo è fondamentalmente un’introduzione all’ambiente JavaCard, in secondo luogo queste limitazioni sono più che accettabili utilizzando risorse hardware anche di un ordine di grandezza superiori a quelle disponibili attualmente.
Per quanto riguarda le JavaCard Applet, cioè le applicazioni eseguibili sulla JavaCard, queste devono presentare una struttura ben definita per funzionare correttamente, in maniera del tutto simile alle applet Java eseguibili dai browser in ambiente PC o workstation. Di seguito è mostrata la struttura di una JavaCard Applet nella sua eccezione più generale:

import javacard.framework.*; // importazione di classi del framework
. . .

public class <Nome JavaCard Applet> extends Applet {
. . . 

 private <Nome JavaCard Applet>() {
  // metodo costruttore
  // si consiglia di creare qui tutti gli oggetti utilizzati dalla JavaCard Applet
 }

 public static void install(APDU apdu) {
  // metodo invocato durante l’installazione della JavaCard Applet
}

public boolean select() {
 // metodo invocato durante la selezione della JavaCard Applet
}

public void deselect() {
 // metodo invocato durante la deselezione della JavaCard Applet
}

public void process(APDU apdu) {
 // metodo invocato durante il process di un comando APDU
}

. . .

}
 

Di seguito sono riportate le descrizioni dei metodi principali, corredati da una breve spiegazione del contesto di chiamata:
 

  • install( ): questo metodo è richiamato dal JCRE come ultimo passo dell’installazione della JavaCard Applet. Notare che, a causa del fatto che tutte le JavaCard Applet sono oggetti persistenti, questo metodo è effettivamente richiamato una sola volta nella vita della JavaCard Applet. All’interno di questo metodo, il programmatore dovrebbe inserire tutte le istruzioni new di creazione degli oggetti che la JavaCard Applet intende utilizzare durante l’esecuzione. Fra le istruzioni del blocco di codice relativo a questo metodo, il programmatore deve inserire anche una chiamata al metodo System.register( ) per la registrazione della JavaCard Applet presso il JCRE. Notare che tutte le istruzioni di questo metodo sono eseguite per default all’interno di una transazione;
  • select( ): questo metodo è richiamato dal JCRE quando una JavaCard Applet è selezionata (questo implica che il JCRE ha ricevuto un APDU riportante un’istruzione di selezione della JavaCard Applet). La JavaCard Applet può accettare o rifiutare la selezione facendo restituire al metodo rispettivamente true o false. Notare che a questo metodo è passato come parametro l’APDU di selezione;
  • deselect( ): questo metodo è richiamato dal JCRE sulla JavaCard Applet correntemente selezionata quando riceve un APDU contenente un’istruzione di selezione. Questa chiamata precede immediatamente la chiamata della select( ) della JavaCard Applet cui la selezione fa riferimento. Questo è quello che accade anche se la JavaCard Applet correntemente selezionata è la stessa cui l’APDU di selezione fa riferimento. Notare che la forzata estrazione della carta dal CAD o un’interruzione d’alimentazione non permettono la chiamata di questo metodo, anche se, al ritorno di condizioni di funzionamento normali, la JavaCard Applet corrente risulta deselezionata.
  • process( ): questo metodo è richiamato dal JCRE immediatamente dopo la chiamata di select( ) la prima volta, ed ogni volta che arriva un APDU di comando dall’entità esterna successivamente, salvo che questo non sia un APDU di selezione per una JavaCard Applet installata o la richiesta di un metodo nativo. Ogni chiamata prevede il passaggio come argomento dell’APDU di comando corrente: questo implica che la prima volta sarà passato l’APDU di selezione, ed ogni volta successiva l’APDU di comando contenente l’istruzione ed eventuali dati. Notare che un APDU di selezione non valido, cioè per cui non esiste una JavaCard Applet con lo AID specificato installata sulla JavaCard, è passato a questo metodo della JavaCard Applet corrente. Per scaricare il contenuto dell’APDU di comando passato tramite argomento in un array di byte, in modo da permetterne la lettura, si utilizza il metodo getBuffer( ). Una volta che sono state svolte le operazioni necessarie, la JavaCard Applet risponde con un APDU di risposta, contenente gli eventuali dati di risposta e la Status Word di risposta. Quest’ultima informa l’entità esterna dello stato finale dell’esecuzione all’interno della JavaCard Applet.


Come si è potuto costatare, la creazione di una JavaCard Applet, e quindi la creazione di un servizio sulla JavaCard, è un’operazione piuttosto semplice. Questo vale in particolare per due motivi: l’utilizzo di un linguaggio ad alto livello quale Java e la possibilità di utilizzare un approccio ad oggetti nella creazione delle funzionalità.
Un analisi dei dispositivi JavaCard non può ritenersi completa senza almeno un accenno ai sistemi di collegamento di questi dispositivi con il mondo esterno. Il mezzo che permette la comunicazione fra le JavaCard ed i dispositivi esterni di controllo, che possono essere PC o workstation oppure dispositivi di controllo dedicati, prendono il nome di CAD (Card Acceptance Device). I CAD sono una gamma di dispositivi estremamente ampia che va da semplici lettori a dispositivi più complessi che presentano, ad esempio, anche un display e un tastierino numerico per l’inserimento di dati. Nella figura 3 è mostrato un tipo di CAD piuttosto diffuso nel campo della JavaCard, un semplice modello di lettore in grado di accettare la JavaCard al suo interno e di stabilire una connessione elettrica tramite l’interfaccia posta sulla superficie della JavaCard:
 
 

Figura 3 – Esemplare di CAD

I CAD sono collegati alle entità che li controlla tramite un’interfaccia dipendente dal tipo d’entità esterna. Nel caso in cui questa sia un personal computer o una workstation, il collegamento è solitamente realizzato tramite una porta seriale o una porta parallela, più raramente tramite una scheda proprietaria da inserire negli slot interni del personal computer. Naturalmente nell’entità esterna che li controlla devono essere installati appositi driver, solitamente forniti dal produttore del CAD, per permettere l’accesso a quest’ultimo dal software di controllo. L’alimentazione per il CAD è solitamente prelevata dall’alimentazione di mouse o tastiera tramite un connettore passante, in alcuni casi può però essere necessario un alimentatore esterno.
 

Conclusioni
Da questo primo assaggio della tecnologia JavaCard si nota immediatamente l’accuratezza utilizzata in fase di progetto e d’implementazione dell’ambiente d’esecuzione. L’ambiente JavaCard permette, infatti, di avere i seguenti principali vantaggi rispetto a tutte le altre tecnologie proprietarie attualmente utilizzate per le JavaCard:

  • utilizzo di un linguaggio di programmazione ad alto livello ben conosciuto da una moltitudine di sviluppatori;
  • supporto alla progettazione e all’implementazione secondo il paradigma della programmazione ad oggetti;
  • standardizzazione delle risorse ed implementazione di un meccanismo di gestione delle estensioni coerente. Notare che questo significa immediatamente portabilità;
  • nessuna particolare richiesta di hardware aggiuntivo rispetto ai dispositivi attualmente disponibili;
  • sufficiente indipendenza dalla quantità di risorse hardware disponibili. Notare che questo significa longevità della tecnologia, poiché il mercato dei dispositivi hardware sembra stia spingendo verso dotazioni di memoria sempre più spinte sui dispositivi SmartCard.
Naturalmente esistono anche alcuni piccoli problemi pratici legati a questa tecnologia, problemi dovuti in maggior parte alla gioventù di questa tecnologia. Questi problemi sono però molto meno preoccupanti rispetto a quelli, eventualmente riscontrabili, su SmartCard contenenti ambienti d’esecuzione proprietari. Lo sforzo d’ampliamento e d’aggiornamento dell’ambiente d’esecuzione è, infatti, comune a tutti i produttori che integrano JavaCard, mentre l’ambiente d’esecuzione proprietario utilizzato da una SmartCard è spesso legato solo ad un sottoinsieme ridotto di produttori di dispositivi.
Un ulteriore punto di forza di questo ambiente è anche il diffondersi sul mercato delle SmartCard del framework OpenCard. Questo framework permette di accedere da un PC o una workstation ad una SmartCard in maniera indipendente dall’interfaccia del CAD, in maniera tale da garantire l’indipendenza delle applicazioni di controllo che utilizzano SmartCard. Tale framework è scritto interamente in Java e si basa su gli stessi concetti e gli stessi obiettivi perseguiti dalla tecnologia JavaCard. Questi due strumenti sono quindi estremamente utili soprattutto quando utilizzati congiuntamente, poiché permettono di realizzare applicazioni orientate a SmartCard completamente portabili fra una moltitudine d’ambienti di controllo e di SmartCard.
 

Bibliografia

Per approfondire i concetti trattati in questo articolo si consiglia la lettura dei seguenti documenti, tutti disponibili nel sito web di SUN dedicato a Java (www.javasoft.com):

[Snm97a]: SUN Microsystems, “Java Card 2.0 Language Subset and Virtual Machine Specification – Revision 1.0 Final”, 1997, www.javasoft.com

[Snm97b]: SUN MicroSystems, “Java Card 2.0 Programming Concepts – Revision 1.0 Final”, 1997, www.javasoft.com

[Snm97c]: SUN MicroSystems, “Java Card 2.0 Application Programming Interfaces – Revision 1.0 Final”, 1997, www.javasoft.com

[Snm98]: SUN MicroSystems, “Java Card Applet Developer’s Guide – Revision 1.12”, 1998, www.javasoft.com
 

Roberto Fabbrica, nato a Ravenna il 28 dicembre 1972, è laureato in Ingegneria Informatica alla Facoltà di Ingegneria dell’Università di Bologna dal 1999. Attualmente lavora come libero professionista, fornendo consulenze come analista programmatore in Visual Basic ad una software house bolognese e collaborando al progetto e all’implementazione di applicazioni Java presso il DEIS (Dipartimento di Elettronica, Informatica e Sistemistica) della Facoltà di Ingegneria dell’Università di Bologna, sede di Cesena.
Può essere contatao all'indirizzo  roberto.fabbrica@libero.it

MokaByte rivista web su Java
MokaByte ricerca nuovi collaboratori
Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it