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
|