MokaByte Numero 28  -  Marzo 1999
Login con il JavaRing
di 
Francesco
Ancona


Presentato allo scorso JavaOne di S.Francisco, il Java Ring non è solo una esercitazione di stile o prova di fattiblità, ma già perfettamente funzionate, rappresenta la base per lo sviluppo di quegli accessori di cui non potremo fare a meno nel  prossimo futuro.

 
Introduzione
 

Ormai e' una constatazione: il digitale con tutte le sue innovazioni sta  penetrando in tutte le nostre vite e i nostri costumi. Provate solo a pensare a quante volte in un giorno utilizziamo un telefonino, il bancomat, la carta di credito, compact disc, e questo senza coinvolgere dispositivi prettamente informatici. Sotto la spinta di Internet, di Java (e di grandi compagnie quali Oracle, Sun) c'e' il tentativo di globalizzare, coinvolgere e far dialogare tutto questi dipositivi digitali. In un contesto del genere si puo' intuire qual'e' uno dei grandi problemi connessi: la sicurezza. 
Per ottenerla ciascun piccolo dispositivo deve possedere dei vincoli di accesso, magari una password costringendo l'utente a impazzire di fronte al crescente numero di chiavi segrete. La smartcard e il JavaRing, fra le molte altre cose che sono in grado di fare, possono risolvere il problema memorizzando al proprio interno, in maniera inattaccabile, tutte le chiavi di accesso possibili. 
Ma andiamo piu' nel dettaglio del JavaRing focalizzandoci proprio sulle sue possibilita' di fare il login per un accesso a un qualunque dispositivo.
Il JavaRing e' un singolo chip con un coprocessore matematico a 1024 bit e un clock; il tutto inserito in un involucro d'acciaio. Questo chip e'dotato di una ROM, una RAM non volatile circa 6K (dunque in grado di memorizzare dei dati ) e tutte le API e JRE necessarie  a eseguire applet java al proprio interno. A differenza degli strati SW  utilizzati dalle vecchie smartcard (c/c++) il JavaRing utilizza Java per una maggiore portabilita' ideale anche per strutture e applicativi distribuiti tipici di Internet. 
Da notare comunque che anche compagnie grosse produttrici di smartcard, come la Bull, si stanno orientando verso la tecnologia java. 
Attraverso il contatto elettrico rappresentato dal rivestimento l'ibutton comunica con l'esterno (PC, webKiosk, o altro) mediante un cavo seriale detto "BlueDot". Si puo' intuire come la possibilita' di memorizzare piu' applet consenta la coesistenza di programmi che svolgono diverse funzioni all'interno dello stesso, piccolo, dispositivo. 
Concludendo l'introduzione si possono cosi'riassumere i 4 componenti fondamentali per ciascuna applicazione con l'iButton:
 

  1. iButtons. 
  2. un host system: questo puo' essere un PC, un laptop, o un palmare. 
  3. un dispositivo reader/writer device per comunicare in e da l'iButton. 
  4. uno strato di software per interfacciare il JavaRing ai computer e per
  5. produrre le informazioni desiderate nel formato desiderato. 

 

Scopo dell'applicazione
 

Strutturalmente il JavaRing o iButton e' stato costruito pensando di mantenere alta la riservatezza dei dati memorizzati al proprio interno e di poter velocemente risalire all'identita' del possessore del Ring. 
I procedimenti piu' significativi adottati in tal senso sono:
 

  1. il rivestimento di acciaio per avere solidita', durata rispetto all'usura (e' testato per 10 anni di utilizzo e inattaccabilita'  rispetto a un tentativo esterno di appropriazione dei dati 
  2. un numero di matricola unico per ciascun iButton costruito: l'ID ROM NUMBER
  3. l'uso del PIN (Personal Identification Number):  in pratica, il dispositivo puo' essere reso inaccessibile settando il commonPIN oppure  bloccandolo completamente tramite un lock.
L'uso di tutti questi livelli di sicurezza, settabili prima di creare una qualsiasi applicazione, consente accessi selezionati a seconda  dell'utente. 
In pratica, settato il PIN, per accedere alle chiavi di accesso memorizzate bisogna sapere qualcosa (PIN) e portare qualcosa (RING).
Questo consente all'utente di utilizzare le chiavi di accesso in maniera trasparente delegando all'applicativo la gestione di tutte le eventuali password che usa nella vita quotidiana. 
Avendo come linea guida questa possibilita' ci si puo' sbizzarrire nel trovare delle applicazioni che coinvolgano un qualunque tipo di accesso; addirittura si puo'pensare l'iButton come chiave per una porta o per l'accensione dell'automobile (da notare che applicazioni di quest genere esistono già). 
Una volta che il Ring ha scaricato le chiavi sull' host quest'ultimo con un database interno o simile,  verifica le password e consente l'accesso. Si potrebbero anche ipotizzare delle applicazioni che utilizzando le chiavi dal JavaRing si connettono a host remoti o a server protetti, il tutto, e lo ripeto, in maniera trasparente all'utente.
 

Codice

Ogni applicazione con il javaRing deve almeno avere 2 parti: la prima, che gestisce i dati, nel Ring, la seconda, che interagisce con l'utente, sull'host system. 
A seconda dell'aumento della complessita' logica degli applicativi la strutturazione delle classi e degli oggetti puo' essere piu' articolata, ma sempre queste due parti devono comparire nell' applicazione.
Ecco un esempio di applicazione in cui si leggono dal Ring 2 chiavi (login e password), la data dell' ultimo login e vi si memorizza la data attuale. 
In aggiunta a tutto questo l'applet puo' memorizzare nuove login e password prima di leggerle. Per motivi di brevita' non inserirò tutto il codice. 
In generale la comunicazione tra host e Ring si sviluppa con il protocollo APDU: tramite una serie di pacchetti, nei cui headers si specificano dei parametri propri per quei dati, l'applet raccoglie e interpreta le istruzioni come azioni da compiere. Tramite lo stesso protocollo il Ring rispedisce i risultati.
 

Applet inserito nel javaring

Gli applet dentro i Ring non iniziano con init() ma in questo caso l'inizializzazione e' divisa in 2 fasi: 
 
 
 
 
 
 
 
 
 
 

1 - installazione

 
//questo e' il costruttore
     loginApp() {
        register();
        data_log_in = new byte[0];
        login = new byte[0];
        password = new byte[0];
     }
     public static void install(APDU apdu){
       new loginApp();
     }

    2- attivazione durante la comunicazione 

     
    public void process(APDU apdu) throws ISOException {
      [..]
     switch (buffer[ISO.OFFSET_INS]){
      default:
         // Don't know what to do with this instruction 
         throw new ISOException(ISO.SW_INS_NOT_SUPPORTED); 
      case LAST_LOG_IN_STORE: 
         loginAppStore(apdu);
         break;
      case LAST_LOG_IN_RETRIEVE:
          loginAppRetrieve(apdu);
          break;
      case LOG_PASWD_STORE:
          passwdAppStore(apdu);
          break;
      case LOG_PASWD_RETRIEVE:
          passwdAppRetrieve(apdu);
          break;
     }
    }
Ciascun case attiva un metodo che espleta le richieste. Valutiamo  ad esempio la lettura del login con loginAppRetrieve(apdu):
 
protected void loginAppRetrieve(APDU apdu){
          temp = new byte[6+data_log_in.length];
          int i=0;
          int j=0;
          for (i=0;i<data_log_in.length;i++) {temp[j]=data_log_in[i]; j++;}
          if (temp != null){ 
            //questa e' la normale sequenza di ritorno dei pacchetti 
            //setta il modo per spedire i dati 
            apdu.setOutgoing(); 
            //setta la lunghezza
            apdu.setOutgoingLength((short)temp.length); 
            //setta i dati, indice inizio , e fine offset 
            apdu.sendBytesLong(temp, (short) 0, (short) temp.length); 
          } 
}
NOTE: queste sono le variabili (sono uguali anche sull'host)
 
final static byte LOGIN_CLA     = (byte) 0x80;
final static byte LAST_LOG_IN_STORE = (byte) 0x10;
final static byte LAST_LOG_IN_RETRIEVE = (byte) 0x20;
final static byte LOG_PASWD_STORE = (byte) 0x30;
final static byte LOG_PASWD_RETRIEVE = (byte) 0x40;
final static byte SELECT_LOGIN_CLA = 0x01;
final static byte SELECT_LOGIN_INS = (byte) 0xA5;
//parametri per gli inserimenti
final static byte BC_P1_SET_LENGTH  = 0x01; 
final static byte BC_P1_NEXT_PACKET = 0x02; 
final static byte BC_P1_LAST_PACKET = 0x03; 
final static short SW_BAD_INS_SEQUENCE = (short) 0x9101;
byte[] data_log_in;
byte[] login;
byte[] password;
short offset;
int  totalLength;
byte[] temp; 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Applet (o applicazione) caricato da un browser 

Attraverso vari tipi interfacce e strati sw sia opensource che specifici del costruttore dell' iButton, l'applet nel browser "sente" il ring, nel senso che si accorge se il JavaRing e' collegato o meno alla seriale, permettendo all'utente di interagire con esso naturalmente anche attraverso l'implementazione di una GUI.
Vediamo quali sono punti fondamentali : per prima cosa l'aspetto legato alle  classi che "ascoltano"
 

//sente che l'anello e' inserito
public void cardInserted(CardTerminalEvent event){
      System.out.println("Java iButton inserted");
      blueDot = event.getSlot();
      channel = blueDot.getCardTerminal().openSlotChannel(blueDot);
      terminal = (iButtonCardTerminal)channel.getCardTerminal();
      iButtonInserted = true;
      //qui si attuano le chiamate per il Ring
      [..]
}
//sente che l'anello e' stato rimosso
public void cardRemoved(CardTerminalEvent event){
      System.out.println("Java iButton removed");
      blueDot = event.getSlot();
      if (blueDot.getSlotID() != 0)
         return;
      iButtonInserted = false;
      blueDot = null;
      terminal = null;
}

Secondo aspetto quello relativo alla registrazione 

//registra l'anello e setta le seriali che utilizza
 protected void startPolling(String nativeDevString)  {
       try {
          SmartCard.start();
          CardTerminalRegistry registry = CardTerminalRegistry.getRegistry();
          registry.addCTListener(this);
       }
       catch (Exception e){
          e.printStackTrace();
       }
   }
Infine la lettura 
public void read() throws loginException   {
      byte[] buffer = new byte[0];
      try{
        //costruisce il comandAPDU cie' il contenitore per dati e parametri
        CommandAPDU businessCardAPDU = new 

           CommandAPDU((byte)LOGIN_CLA, (byte) LAST_LOG_IN_RETRIEVE, (byte)0,

           (byte)0, buffer, (byte)0);
        //cattura il response APDU l'oggetto al cui 
        // interno vi sono i dati letti
        ResponseAPDU response = channel.sendAPDU(businessCardAPDU);
        //ba[] rappresenta i dati
        byte[] ba=response.data();
        [...] 
      } 
      catch  (CardTerminalException e) {
         System.out.println("non riesco a comunicare con la card"+e.statusWord());
      }
   } 
Alcune considerazioni sugli strati SW utilizzati

Come si puo' valutare dagli import immessi nel codice Java implementato, tutte le API provengono da 3 pacchetti:

  1.  jibapi: questo pacchetto e' quello fornitomi dal costruttore del Ring: ha delle funzioni specifiche che permettono la comunicazione con il JavaRing quali l'inizializzazione del PIN o l'azionamento del garbage collector per le classi java. La dallas SemiConductor fornisce anche, per un maggior controllo del dispositivo, un interfaccia GUI apduSender che utilizza direttamente queste API. 

  2.  

     
     
     

  3. opencard framework: sono principalmente preposte alla comunicazione fra l'ambiente esterno e il JavaRing attraverso lo standard APDU (application protocol  data unit). Nonostante l'alto livello di astrazione delle classi del pacchetto opencard framework, il formato dei pacchetti durante la  comunicazione e' array di byte, cosa che rende piu' ardua la lettura e scrittura nel Ring rispetto ai piu' comodi InputStream. La scelta del formato dei pacchetti e' obbligata dalla memoria disponibile nel ring ad oggi ancora abbastanza limitata

  4.  

     
     
     

  5. javacard2.0 framework: sono il motore che fa "girare" gli applet all'interno del Ring e fanno anch'esse parte di uno standard verificato da Sun. Eccettuato il primo pacchetto, gli altri 2 sono degli standard che vengono utilizzati anche per lo sviluppo delle smartcard (che utilizzano java naturalmente) e questo rende, eventualmente, abbastanza agevole il passaggio tra questo stesso dispositivo e il JavaRing e viceversa.  L'ultima considerazione riguarda l'inserimento dell'applet nel Ring (ma la stessa cosa avviene per le smartcard) eccone uno schema
In pratica i file.class vengono "macinati" da un opportuno convertitore che li formatta in maniera accettabile per la JVM del Ring. Nel caso dell'iButton tale convertitore e'dato dal programma Java BuildJiBlet.

 
 

MokaByte Web  1999 - www.mokabyte.it

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