Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Firmare un Applet

Assegnare ad un Applet un certificato digitale per superare i vincoli di sicurezza
Assegnare ad un Applet un certificato digitale per superare i vincoli di sicurezza
Link copiato negli appunti

Molti sanno cos'è un Applet e, magari, avranno anche sviluppato qualche simpatica applicazione in Java da poter eseguire sulle proprie pagine web. Probabilmente, però, non altrettanti conoscono le limitazioni cui sono soggetti gli Applet e, se si è testato il proprio Applet unicamente con l'Applet Viewer fornito con il J2SE (magari utilizzando Eclipse come strumento di sviluppo), si potrebbe correre il rischio di restare delusi e sorpresi nel vedere scatenarsi eccezioni di tipo java.security.AccessControlException (o java.lang.SecurityException) quando si testa l'Applet in una effettiva pagina web.

Vediamo, allora, di approfondire meglio questo genere di concetti, cercando di trovare una risposta che ci chiarisca le idee relativamente alle seguenti domande:

  • Quali sono le limitazioni di un Applet?
  • Perché esistono delle limitazioni sugli Applet?
  • Perchè l'Applet Viewer potrebbe trarci in inganno?
  • È possibile superare le limitazioni sugli Applet? E, se si, come?

Il codice di un'applicazione Java viene considerato affidabile (trusted) dalla Java Virtual Machine in quanto si presume che esso venga eseguito volontariamente dall'utente di un computer. Un Applet, al contrario, è valutato dalla JVM come codice non affidabile (untrusted) e pertanto potenzialmente pericoloso per la sicurezza della macchina e dei dati in essa contenuti.I motivi sono facilmente intuibili: si pensi, ad esempio, al fatto che un Applet, se fosse libero di eseguire qualunque operazione, potrebbe accedere liberamente al file system di una macchina leggendo qualunque informazione o, ancora peggio, cancellando qualsiasi file!

Anche le limitazioni sulla connessione via Socket hanno una logica incentrata sulla sicurezza: infatti, un Applet può aprire un Socket soltanto verso il server da cui lo stesso Applet è stato scaricato. E così, per analoghe ragioni, è fatto divieto agli Applet di caricare librerie, invocare metodi nativi ed eseguire processi su un client.

In generale, un browser esegue il codice di un Applet all'interno di una sandbox (letteralmente "buca di sabbia") che ne controlla le funzionalità imponendo le limitazioni di cui si è parlato.

Dunque, ci si potrebbe chiedere: gli Applet vanno utilizzati unicamente per creare effetti grafici accattivanti e gestire funzionalità limitate? La risposta è no. Gli Applet costituiscono, sicuramente, un mezzo sufficientemente potente per l'esecuzione di applicazioni attraverso il Web. È chiaro che se si sta pensando di implementare un'applicazione di tipo enterprise, le soluzioni da adottare sono altre (argomento che esula dal contenuto di questo articolo) ma è importante sapere che è possibile ampliare lo spettro di azione degli Applet superando le limitazioni di cui si è fatta menzione in precedenza. Non ci resta che vedere come fare per rendere un Applet un'applicazione trusted.

Esempio: Un Applet che crea un file su disco

Per rendere la comprensione dei concetti più chiara, usiamo un semplice esempio: un applet che crei un file di testo (hello.txt) sul disco fisso, il cui contenuto sia la classica stringa "Hello World". Vediamo, quindi, per prima cosa il codice dell'Applet:

Listato 1. Codice dell'applet

import java.applet.Applet;
import java.awt.Graphics;
import java.io.*;
import java.awt.Color;

public class WriteToDiskApplet extends Applet
{
  public String createFile()
  {
    String strReturn ;
    String fileName = "";
    setBackground(Color.white);
    try
    {
      fileName = System.getProperty("user.home");
      fileName += System.getProperty("file.separator");
      fileName += "hello.txt";
      
      String msg = "Hello Worldn";
  
      FileWriter fos = new FileWriter(fileName);
      fos.write(msg, 0, msg.length());
      fos.close();
      strReturn = new String("File " + fileName + " creato con
successo");
    }
    catch (Exception e)
    {
      System.out.println("Eccezione di tipo " + e);
      e.printStackTrace();
      strReturn = new String("Impossibile creare il file!");   
    }
    return strReturn;
  } 

  public void paint(Graphics g)
  {
    g.setColor(Color.blue);
    g.drawString("Applet WriteToDiskApplet", 120, 50);
    g.setColor(Color.RED);  
    g.drawString(createFile(), 50, 100);
  } 
}

Si cerca di creare, all'interno del blocco try, il file hello.txt nella cartella "home" di sistema dell'utente connesso (per l'utente generico "pippo" di Windows corrisponde a C:Documents and Settingspippo). Nel caso in cui la scrittura del file si sia conclusa con esito positivo, l'Applet visualizza il messaggio: "File ...hello.txt creato con successo" In caso contrario (gestito all'interno del blocco catch) viene visualizzato il messaggio "Impossibile creare il file hello.txt".

Supponiamo che per scrivere il codice precedente sia stato utilizzato Eclipse e, pertanto, sia stato fatto uso dei suoi wizard per la creazione del progetto e della classe WriteToDiskApplet.

A questo punto non ci resta che testare il nostro Applet. Lo faremo prima tramite l'AppletViewer fornito con il J2SE e, successivamente, inserendo l'Applet stesso all'interno di una pagina html.

Utilizzando l'AppletViewer (lo si può fare eseguendo, ad esempio, l'Applet direttamente da Eclipse) il risultato che si ottiene sembrerebbe smentire tutto quello che si è scritto in precedenza! Il file hello.txt viene correttamente scritto sulla nostra directory senza nessun problema e nessuna eccezione. La figura seguente illustra il risultato a video:

Figura 1. Applet in esecuzione nell'AppletViewer
Applet in esecuzione nell'AppletViewer

Vediamo, invece il risultato inserendo l'Applet in una pagina Web. Ad esempio, la seguente:

Listato 2. Pagina html ospite dell'Applet

<html>
<head>
<title>Un Applet che crea un file su Disco</title>
</head>
<body>
<applet code="WriteToDiskApplet.class"
  archive="WriteToDiskApplet.jar"
  width=400 height=400>
  <param name=file value="/etc/inet/hosts" />
</applet>
</body>
</html>

Creiamo un file .jar contenente il .class del nostro Applet attraverso l'istruzione:

jar -cvf WriteToDiskApplet.jar WriteToDiskApplet.class

sarebbe sufficiente inserire direttamente il .class dalla pagina html ma è buona norma utilizzare sempre un .jar.

Apriamo la pagina Web sul browser e vediamo cosa accade. Il risultato è decisamente diverso. Non è stato possibile scrivere alcun file sul file system della nostra macchina:

Figura 2. Applet in esecuzione nel browser
Applet in esecuzione nel browser

Se si apre la Java Console dal menù del browser ci si accorge che si è scatenata un'eccezione di tipo java.security.AccessControlException addirittura al momento di ricavare la proprietà user.home del sistema e, quindi, prima di creare il file su disco:

Figura 3. Eccezioni nella console Java
Eccezioni nella console Java

Policy file per la sicurezza

Anche se avessimo evitato di richiedere le proprietà user.home e file.separator al sistema, inserendo direttamente il path in cui andare a salvare il file, avremmo ottenuto un risultato analogo. Insomma, la JVM blocca determinate istruzioni dell'Applet per motivi di sicurezza. Ma, allora, ritorna una delle domande poste all'inizio: perchè l'Applet Viewer sembra trarci in inganno?

La spiegazione è da ricercare nel file java.policy.applet che Eclipse crea automaticamente nella directory stessa dell'Applet.

Contenutro del file "java.policy.applet"

/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002 */
/* DO NOT EDIT */


grant{
  permission java.security.AllPermission;
};

La JVM implementa il concetto di sicurezza avvalendosi, tra l'altro, dell'utilizzo di un policy file, che si trova al seguente percorso:

$JAVA_HOME/jre/lib/security/java.policy

La prima parte di questo file, ad esempio, contiene la seguente istruzione (nella sintassi propria dei policy file):

Codice di un comune policy file

// Standard extensions get all permissions by default


grant codeBase "file:${{java.ext.dirs}}/*" {
  permission java.security.AllPermission;
};

che consente a qualunque programma che si trovi nella directory $JAVA_HOME/lib/ext/* di eseguire qualsivoglia operazione.

Il file java.policy.applet che Eclipse crea nella directory del nostro Applet è molto simile ma, come si può notare, non prevede alcun codebase. In altre parole, viene garantita, al codice proveniente da qualunque codebase, la possibilità di eseguire qualunque tipo operazione compresa, quindi, la creazione di file su ogni directory del file system. Ciò perché si è dato per buono che il programmatore che scriva un Applet su una macchina possa poter testare il proprio codice (sulla stessa macchina) senza doversi preoccupare di problemi inerenti la sicurezza.

Chiarito questo cerchiamo di risolvere il problema principale: quello di far girare anche on line il nostro Applet. La soluzione consiste nel creare degli Applet firmati (signed Applet) che diano una certa garanzia a coloro che li visualizzano sul browser.

Certificare per l'applet

Un signed Applet è un Applet che viene associato ad un certificato digitale prodotto da una certificate authority o ... da noi stessi (naturalmente con le debite differenze in termini di credibilità)! In tal modo, quando un utente si trovi a visitare un sito in cui è presente un Applet firmato, la prima cosa che gli si presenterà a video è una finestra di dialogo che fornirà maggiori informazioni sul certificato digitale che si è utilizzato per firmare l'Applet.

Vedremo, ora, come creare un certificato digitale e firmare con esso il nostro WriteToDiskApplet. Il tutto con l'utilizzo dei tool messi a disposizione dal J2SE.

Creazione della coppia di chiavi (pubblica e privata)

Il nostro Applet ed, in particolare, il nostro file .JAR, dovrà essere firmato utilizzando una chiave privata prodotta dall'autore del JAR stesso. La verifica della firma potrà essere, quindi, effettuata attraverso una chiave pubblica che, essendo l'unica in grado di "accoppiarsi" con la chiave privata del JAR, ne garantirà l'autenticità. Per creare la coppia di chiavi si utilizza il programma keytool, con la seguente sintassi:

keytool -genkey -alias firmaApplet -keystore marcokeystore
  • -genkey indica che si vuole generare una coppia di chiavi pubblica/privata
  • -alias firmaApplet consente di assegnare alla coppia di chiavi da generare un alias che, in questo caso, abbiamo denominato firmaApplet
  • -keystore marcokeystore crea un database per le chiavi generate, denominato marcokeystore.

Lanciando il comando precedente verranno richiesti ulteriori informazioni, come mostrato nella figura seguente:

Figura 4. Informazioni per la creazione del certificato
Richiesta informazioni per la creazione del certificato

E al termine, verrà creata una coppia di chiavi che sarà immagazzinata nel database marcokeystore. Esistono numerose opzioni per il comando keytool. Per poterle visualizzare tutte (con la descrizione della relativa funzionalità)) è sufficiente digitare il comando:

keytool -help

Firma del file JAR

È arrivato il momento di firmare il nostro .JAR utilizzando le chiavi appena prodotte. A tale scopo si utilizza il programma jarsigner che include anche la funzionalità di verifica della firma stessa.

jarsigner -keystore marcokeystore -signedjar  SignedWriteToDiskApplet.jar WriteToDiskApplet.jar firmaApplet
  • -keystore indica il database dove abbiamo salvato le chiavi in precedenza
  • -signedjar indica il nome del nuovo file JAR firmato che vogliamo generare
  • firmaApplet è l'alias utilizzato per identificare le chiavi generate in precedenza
Figura 5. Esecuzione del comando jarsigner
Esecuzione del comando jarsigner

Al termine dell'esecuzione avremo ottenuto un nuovo file jar, denominato SignedWriteToDisk, firmato digitalmente da noi.

Ritentiamo l'esecuzione

Se, adesso, proviamo a ricaricare la pagina web contenente l'Applet noteremo che verrà visualizzata la seguente finestra di dialogo:

Figura 6. Maschera per accettare il certificato
Maschera per accettare il certificato

Che ci informa che l'Applet che stiamo tentando di caricare è fornito di certificato digitale, anche se quest'ultimo non è stato rilasciato da una certificate authority, come si evince dalla finestra seguente (ottenuta a partire dalla precedente, cliccando su "Ulteriori informazioni").

Figura 7. Ulteriori informazioni
Ulteriori informazioni

Cliccando, ora, sulla voce "Dettagli certificato…" potremo visionare tutte le informazioni del certificato digitale che abbiamo associato al nostro JAR (e, quindi, al nostro Applet):

Figura 8. Dettagli del certificato
Dettagli del certificato

Chiudiamo le finestre di dialogo mostrate nelle figure precedenti. Se si sceglie di dare fiducia al certificato che accompagna l'Applet, basterà che l'utente clicchi sul pulsante Esegui per mandare in esecuzione l'Applet sulla propria macchina. Il risultato sarà, finalmente, quello sperato: la creazione del file hello.txt sul disco dell'utente.

Ti consigliamo anche