La sicurezza di Java

Creative Commons License Questo/a opera è pubblicato sotto una Licenza Creative Commons.

Le applet e la sicurezza

Di Michele Costabile

Java ha una eccellente reputazione per quanto riguarda la sicurezza. Fino dalla nascita, infatti, gli architetti del linguaggio e dell’ambiente operativo si sono posti il problema di scongiurare la possibilità di creare virus, cavalli di Troia o altro software dannoso usando il linguaggio creato da Sun.

La cultura aziendale di Sun per quanto riguarda le reti è una delle più antiche nel mondo dell’informatica. Il fenomeno della diffusione di massa di virus aveva già una decina di anni all’epoca della nascita di Java, quando ancora il mezzo di propagazione principale era l’infezione di dischetti da 360 Kbyte.

Era logico, quindi, prevedere che la propagazione dei virus avrebbe avuto un impulso straordinario con il progresso dell’interconnessione mondiale di computer permesso da Internet, in fin dei conti, il primo virus conosciuto per la capacità di propagarsi in rete era del 1970, dieci anni prima della nascita di Windows e venticinque anni prima dell’uscita di Java.

Dato che Java si proponeva come un ambiente di esecuzione ideale per le applicazioni costruite sopra il browser e diffuse attraverso la rete, il problema della sicurezza dell’ambiente di esecuzione è stato posto in cima alla lista delle priorità fin dall’inizio.

Il problema della sicurezza è stato affrontato con tecniche radicali e innovative traendo vantaggio anche dall’architettura dell’ambiente di esecuzione di Java, basata su una macchina virtuale.

Queste tecniche vanno oltre il concetto tradizionale, di proteggere il computer dagli utenti.

Proteggere il computer dagli utenti

I meccanismi di protezione tradizionali, quelli con cui Unix è nato nel 1970 e che i PC hanno acquisito compiutamente da Windows 2000 in poi, si basano sui diritti assegnati agli utenti e sulla protezione del codice critico dagli utenti.

Il sistema operativo conserva l’ultima parola sui diritti degli utenti usando meccanismi di controllo messi a disposizione dalla Cpu, che consentono di limitare l’accesso di un programma alla memoria specificamente allocata per il processo in esecuzione e impedendo di scrivere sulle porte di input e output.

Un programma in esecuzione, quindi, non può danneggiare altri che sé stesso scrivendo in memoria e non può avere accesso all’hardware della macchina se non attraverso il sistema operativo.

Le chiamate al sistema operativo richiedono il passaggio della Cpu da una modalità di esecuzione protetta a una modalità di esecuzione privilegiata riservata al sistema operativo.

Il sistema operativo, quindi ha la possibilità di realizzare le politiche di protezione delle risorse critiche che decide di attuare. Con questi meccanismi Unix o Windows 2000 e XP mettono in atto i meccanismi di protezione, come i diritti di accesso ai file e alle risorse di sistema. Questi diritti sono assegnati agli utenti.

I meccanismi di protezione basati sui diritti degli utenti non proteggono però gli utenti dal codice che eseguono. Quando il sistema operativo ha caricato in memoria e collegato al suo ambiente di esecuzione del codice eseguibile non c’è nulla che possa fermare il programma.

Codice creato per nuocere può fare quello che desidera con i file del malcapitato utente che lo esegue. Il sistema operativo si limita a proteggere le sue aree riservate e i file degli altri utenti.

Gli antivirus cercano di controllare l’esecuzione del codice per prevenire azioni malevole, ma il sistema operativo resta neutrale.

Proteggere gli utenti dal computer

L’approccio alla sicurezza che è stato usato con Java è duale rispetto a quello descritto sopra, si tratta cioè di difendere gli utenti e i loro dati da programmi potenzialmente dannosi, come virus e trojan.

In un ambiente di esecuzione come quello di Windows, il codice viene eseguito direttamente dal processore, quindi l’esecuzione di un programma è subordinata solo ai criteri di protezione applicati dall’hardware.

L’ambiente di esecuzione di Java, invece, è centrato su una macchina virtuale, che sta fra il codice da eseguire e il sistema operativo. Il codice Java prima di andare in esecuzione deve essere interpretato e caricato in memoria dal caricatore della macchina virtuale.

La Jvm (Java Virtual Machine) oltre a mettere il programma in condizioni di andare in esecuzione può anche applicare delle politiche di protezione che proteggano l’ambiente di esecuzione dal codice.

In effetti, il codice delle classi Java viene verificato prima dell’esecuzione per assicurare che una classe con codice binario malformato ad arte possa aprire falle nell’ambiente di esecuzione. La Jvm verifica anche che la classe corrisponda ad alcuni criteri generali di correttezza.

Oltre a questi controlli formali, si sono individuate delle aree critiche del codice. Nei punti nevralgici che sono stati rilevati è stata data la parola al SecurityManager prima dell’esecuzione.

Esempi di codice sottoposto a controllo sono le funzioni della classe File che permettono di leggere dati personali dell’utente o manomettere il file system, le funzioni della classe Socket che consentono collegarsi con altri computer e sfruttare il computer di un utente per attaccare un sito, le funzioni della classe System che danno accesso a informazioni sul computer dell’utente che possono essere sfruttate per pianificare un attacco.

Per descrivere in modo pittoresco l’idea di un ambiente controllato, è stato coniato il termine sandbox, che indica la cassetta di sabbia in cui si possono lasciare giocare i bambini al parco con relativa tranquillità.

Le applet Java sono confinate nella loro sandbox e non ne possono uscire senza un intervento amministrativo. Questo protegge efficacemente l’utente dal computer. In effetti, dopo una decina di anni di crescita di Java, la reputazione dell’ambiente per quanto riguarda la sicurezza è eccellente.

Una questione politica

Le politiche di protezione dell’ambiente di esecuzione non sono fondate sull’utente collegato al sistema – questo resta il territorio del sistema operativo – ma sulla relazione di fiducia fra l’utente collegato al sistema e il codice in esecuzione.

Sono la provenienza e la tracciabilità del codice a determinare il grado di fiducia accordato dall’utente al codice è da eseguire. Un’applet scaricata da Internet ha un grado di attendibilità molto più basso di una funzione di libreria o di un’applicazione locale.

Le politiche di sicurezza sono espresse attraverso direttive contenute in un policy file e applicano restrizioni alla libertà di manovre del codice, che possono essere basate sulla posizione da cui è stato caricata una classe, sulla presenza di una firma digitale che ne attesti la provenienza e, in questo caso, sull’autore del codice firmato.

L’unico esempio simile di identificazione del codice che troviamo su Windows riguarda i driver. La casa di Redmond ha lanciato un piano di certificazione e firma dei driver, allo scopo di separare le responsabilità dei malfunzionamenti del sistema fra il codice Microsoft e il codice di terze parti.

Quando si installa un driver non firmato Windows mette in guardia l’utente da possibili rischi. Dopo l’installazione, comunque, il software acquisisce sempre pieni diritti sulla macchina. L’utente può proteggersi non installando, ma non può applicare restrizioni al software non completamente fidato.

Dove trovare i policy file

L’ambiente di esecuzione Java è protetto da un policy file globale. Ogni utente del sistema (anche su Windows) può avere un file di direttive di protezione personale. Quando si avvia la macchina virtuale viene letto per primo il file globale e quindi il file personale dell’utente. Se nessuno dei due file è stato creato, si usa un insieme di permessi predefinito.

Il percorso del file contenente le impostazioni di protezione globale è

$(java.home)/lib/security/java.policy

Abbiamo indicato con $(java..home) il valore della proprietà di sistema java.home, che può essere letto con

System.getProperty("java.home");

La policy principale può contenere la poszione di policy file supplementari.

Il file contenente la politica di sicurezza di uno specifico utente si trova nella home directory dell’utente. Questa dipende dal sistema operativo e in Windows dipende dalla versione del sistema.

Su una macchina con Windows XP, la home directory dell’utente tizio è, in generale,

C:\Documents and Settings\Tizio

Su Windows 98 o NT il percorso è diverso. La home directory dovrebbe corrispondere alla variabile %userProfile%. Per togliersi ogni dubbio sull’opinione che Java ha di qual è la home directory conviene stampare il valore di

System.getProperty("user.home");

Il nome del file di policy dell’utente è .java.policy. Attenzione al punto iniziale.

Su Unix o Linux, la home directory è quella in cui ci si trova per default dopo il login, o dando il comando cd senza parametri in una finestra di comando.

Qualche esempio di policy

L’installazione di default del Jdk 1.5 dà tutti i poteri al codice di libreria, ecco come si esprime questa direttiva

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

la parola chiave grant apre una direttiva che concede diritti, segue la descrizione del soggetto della direttiva, in questo caso il codice caricato dai file contenuti nella proprietà di sistema java.ext.dirs.

Fra parentesi graffe troviamo la lista dei permessi accordati, in questo caso, sbrigativamente, si tratta di tutti i permessi.

Ecco un esempio più restrittivo: concediamo al codice caricato dalla directory /home/sysadmin il permesso di leggere il file /tmp/abc

grant codeBase “file:/home/sysadmin/” {

permission java.io.FilePermission "/tmp/abc", "read";
};

Come si vede, possiamo essere molto specifici. Consideriamo anche che possiamo impostare protezioni basate sul sito di provenienza allo stesso modo:

grant codebase "http://www.games.com",
signedBy "Duke",
principal javax.security.auth.x500.X500Principal "cn=Alice" {
permission java.io.FilePermission "/tmp/games", "read, write";
};

In questo esempio abbiamo una restrizione che riguarda il codice scaricato da http://www.games.com, firmato all’origine da Duke e eseguito localmente da un utente che ha identità cn=Alice nel server Ldap aziendale.

La sintassi dei policy file è descritta nella guida in linea di Java all’indirizzo http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html.

Il SecurityManager all’opera

Adesso andiamo a vedere come possiamo renderci conto dell’influenza del security manager su un semplice programma che cerca di eseguire un processo sulla macchina dell’utente.

Il codice del programma è quello nel listato e il punto incriminato è quello in cui si esegue un programma

Runtime.getRuntime().exec(fileName);

Il resto del codice è macchinario praticamente standard.

La classe è derivata da Applet, di conseguenza ha un metodo paint, che serve a disegnare sul video, quindi a interagire con l’utente.

Il metodo init è realizzato per avere la possibilità di inizializzare delle variabili una volta, al caricamento dell’applet. La variabile che viene

Nel metodo start viene creato un processo in un blocco try/catch, per gestire i potenziali errori. La scelta di usare start per ospitare il codice di test ha per conseguenza che l’esecuzione di un programma sarà tentata ogni volta che si visita la pagina contenente l’applet.

Il main del programma inizializza l’ambiente e chiama i metodi dell’applet in modo simile a quanto farebbe il browser. Il codice del main permette quindi di lanciare l’applet come se fosse un’applicazione autonoma. Da non sottovalutare il listener per l’evento windowClosing aggiunto con l’istruzione

f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
// Termina il programma
System.exit(0);
}
});

Se dimentichiamo questo codice sarà più difficile chiudere l’applicazione, dato che non risponderà al consueto clic sul pulsante con la X in alto a destra.

Lancio come applicazione: rose e fiori

Compiliamo il programma e mandiamolo in esecuzione con la riga di comando

java -classpath . runFile

Si aprirà la finestra del notepad mandato in esecuzione dal nostro programma, a meno che la posizione della cartella di sistema di Windows non sia C:\windows\system32, come può accadere in un’installazione personalizzata.

Con le impostazioni predefinite, tutto il codice eseguito localmente è considerato degno di fiducia dall’ambiente Java.

Alt, posto di blocco

Scassiamo subito il giocattolo, mandando in esecuzione il programma con la riga di comando

java -classpath . -Djava.security.manager runFile

L’applicazione Java andrà in esecuzione, ma non vedremo comparire la finestra del notepad. Sulla riga di comando, infatti, abbiamo usato un’opzione di lancio gestita non dal nostro programma ma dall’ambiente Java, che richiede l’esecuzione sotto il controllo di un security manager, che blocca il programma sulla base della politica di protezione di default.

La differenza principale fra l’ambiente di esecuzione di un’applicazione e di un’applet sta nella presenza di un security manager per l’applet.

Non sono solo le applet a essere controllate da un security manager, ma anche il codice caricato in un application server, come Tomcat, WebSphere, WebLogic o iPlanet viene tenuto sotto controllo. Non si può consentire, per esempio, che qualcuno carichi una pagina Jsp sul server che esegue System.exit(1) spegnendo il server.

Ecco un piccolo estratto del lungo file di policy di Tomcat

// These permissions apply to javac
grant codeBase "file:${java.home}/lib/-" {
  permission java.security.AllPermission;
};
// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
  permission java.security.AllPermission;
};

Tomcat ha politiche di sicurezza più lasche, per esempio, di iPlanet. Può capitare, quindi, che applicazioni testate con un server applicativo si scontrino con le politiche di sicurezza di un altro.

L’errore nel blocco di codice critico viene gestito dal programma impostando una variabile globale,message, che viene usata per dare segnalazione all’utente nel metodo paint.

try {
if (osName.indexOf("Windows") == -1) {
message = "non posso eseguire " + fileName + " su " + osName;

  Runtime.getRuntime().exec(fileName);
  message = "Ho eseguito " + fileName;
} catch (SecurityException e)
  message = "Ho causato una security exception " + e;

} catch (IOException e) {

  message = "Ho causato una i/o exception " + e;
}

Nel nostro caso, vedremo nella finestra dell’applicazione la scritta “Ho causato una security exception “.

Aggirare il blocco

Il codice che funzionava senza security manager viene fermato dal security manager con la policy di sistema. La strada più semplice per rispristinare l’esecuzione è definire una politica di protezione esplicita, meno restrittiva.

Con un editor di testi creiamo il file no.policy e scriviamoci dentro

grant {
permission java.io.FilePermission "<<ALL FILES>>",
"execute";
};

Lanciamo il programma richiedendo alla macchina virtuale di usare il security manager, come prima, ma stavolta richiediamo di applicare la policy che abbiamo appena definito esplicitamente.

java -classpath . -Djava.security.manager -Djava.security.policy=no.policy RunFile

Questa volta il programma funziona: si aprirà la finestra del notepad e il messaggio mostrato nella finestra dell’applicazione sarà “ho eseguito c:\windows\system32\notepad.exe”. Il security manager, quindi, può essere configurato. Nel momento in cui siamo convinti di un’applicazione, poi possiamo assegnare permanentemente i permessi relativi. La politica che abbiamo definito è troppo lasca. In primo luogo non pone restrizioni di dominio, cioè si applica a tutte le applicazioni indistintamente. In secondo luogo consente di eseguire tutti i file. Possiamo facilmente restringere la policy in modo da consentire solo l’esecuzione del notepad. Creiamo il file notepad.policy con il contenuto seguente

grant {
permission java.io.FilePermission "C:\\windows\\system32\\notepad.exe",
"execute";
};

Il programma funziona correttamente, lanciato con le opzioni

java -classpath . -Djava.security.manager -Djava.security.policy=notepad.policy RunFile

Se adesso cambiamo il nome del file nella policy, per esempio cambiando notepat in zotepad, il programma di test non riuscirà a eseguire il processo. Adesso proviamo a restringere il permesso di esecuzione solo al codice caricato in una certa posizione con questo file di policy

grant codeBase "file:/C:/programmi/runner" {
permission java.io.FilePermission "C:\\windows\\system32\\notepad.exe",
"execute";
};

Stavolta il programma funzionerà solo se lo carichiamo nella directory C:\programmi\runner. Una copia del programma in una directory diversa non riuscirà a eseguire il notepad.

E se si trattasse di un’applet?

Proviamo ora a eseguire il codice come applet. Scriviamo una pagina Html minimale per ospitare la nostra classe. Ecco un esempio:

			<html>
			<head>
			<title>Esecuzione del notepad</title>
			</head>
			<body>
			<h1>Esempio: Eseguire il notepad</h1>
			<hr>
			<applet codebase="." code="RunFile.class" width="1024" height=
			"50">
			</applet>
			<hr>
			</body>
			</html>
		

Si noti che conviene abbondare con la larghezza dell’applet, 1024 nel nostro caso, in modo da non troncare i messaggi di errore che sono piuttosto lunghi, ma eloquenti.

Possiamo eseguire il programma in un browser o nell’appletviewer, un eseguibile che fa parte del Jdk. Sia con Firefox, sia con Explorer, sia con l’appletviewer non avremo risultati fino a che non andiamo a rilassare i criteri di sicurezza copiando una delle policy che abbiamo creato, per esempio notepad1.policy, nella cartella C:\Documents and settings\nomeutente rinominando il file .java.policy.

Naturalmente non abbiamo riscontrato differenze nell’esecuzione del codice nell’appletviewer rispetto ai browser, perché abbiamo installato la macchina virtuale di Sun accettando il default proposto di impostarla come macchina predefinita per Mozilla e Explorer.

Documenti prego

Quello che abbiamo visto fino a ora è un insieme di strumenti potenti per mantenere il controllo sul codice non affidabile e eseguirlo in modo sicuro, insieme ai meccanismi con cui concedere permessi di esecuzione in modo generico o estremamente puntuale.

Come abbiamo detto, però, la fiducia che si può concedere al codice dipende dalla sicurezza con cui possiamo identificare chi lo ha prodotto e garantirci che il codice non sia stato modificato dopo la creazione, per esempio da un creatore di virus in vena di esperimenti.

Per risolvere il problema di garantire l’autenticità e l’integrità di un file si fa ricorso alla firma digitale con un certificato.

Un certificato è una chiave di sicurezza che contiene un’affermazione di identità (io sono il tale) un riferimento a un ente garante (chi rilascia il certificato) e dei codici di controllo che permettono di stabilire che il certificato sia integro, in modo da non permettere di modificare le asserzioni contenute nel certificato senza fargli perdere di validità.

Il certificato può essere associato a una coppia di chiavi per la crittografia, una pubblica e una privata. La chiave pubblica permette di decifrare un documento, ma non consente di ottenere una cifratura corretta. Il documento, cifrato, quindi può essere ricondotto all’originale, ma un originale modificato non può essere cifrato nuovamente se non scoprendo la chiave privata con un procedimento molto lungo.

La combinazione di queste due cose permette la firma digitale, cioè la creazione di un documento accompagnato da un codice di controllo che permette di verificarne l’integrità, su un certificato che ne garantisce l’autenticità e l’identità di chi emette il documento.

Questo processo può essere applicato al codice in modo da sigillarlo e garantirne l’autenticità. Naturalmente questo non assicura che il codice non faccia danni, ma permette di avere un soggetto con cui prendersela per i danni.

Privilegi di una firma

Il codice firmato viene trattato in modo privilegiato dal security manager.

Si può fare una prova navigando all’indirizzo http://java.sun.com/security/signExample12/signedPluginEx.html. L’applet Java che può essere caricata a questo indirizzo crea un file nella directory radice del disco C, cosa che normalmente non sarebbe concessa ad un’applet.

Il security manager riconosce che il codice ha una firma digitale, che garantisce che è prodotto da Duke, il personaggio mascotte di Java.

Nonostante la firma, comunque, il codice non conquista privilegi in modo invisibile. Al lancio dell’applet, infatti, una finestra di dialogo avvisa del fatto che il codice è firmato, ma ci sono problemi con il certificato.

In primo luogo, il certificato non è emesso da una fonte attendibile, in secondo luogo è scaduto.

La finestra di dialogo permette di visualizzare i dettagli del certificato e verificare che la data di scadenza è nel 2002 e che l’ente che certifica l’identità di Duke è Duke stesso. Il certificato, cioè, è un’autocertificazione, in Inglese è self signed.

Stando così le cose, la parola sull’affidabilità del certificato sta all’utente. Un certificato in cui la mia banca dichiara di essere la mia banca ha un’affidabilità diversa da un certificato in cui Pinco Pallino attesta di essere Pinco Pallino.

Abbiamo la possibilità di respingere il certificato, e negare i diritti di accesso al codice caricato dalla pagina Web, oppure lo possiamo accettare temporaneamente o permanentemente. Se scegliamo il tasto Sempre dovremo disinstallare il certificato per ritirare la fiducia a Duke.

Dopo avere accettato il certificato troveremo nella radice del disco C un file di nome tmpfoo, creato dall’applet. Per default le applet firmate hanno tutti i diritti di accesso. Si può modificare la policy di sistema in modo da forzare l’applicazione di misure di protezione anche alle applet firmate. La guida per lo sviluppatore del Java plugin spiega come creare un permesso fittizio usePolicy per forzare l’applicazione di restrizioni anche al codice firmato.

L’ esperimento con un’applet firmata ci insegna che esiste un modo più semplice di realizzare applet che hanno bisogno di privilegi particolari per andare in esecuzione: è la firma digitale. Se firmiamo un’applet, infatti, non occorre installare un policy file sulla macchina dell’utente per aumentare i privilegi del programma.

Si può anche combinare la firma digitale con codebase in una direttiva di protezione.

grant CodeBase “http://mytech.it/&#8221;, signedBy “Pcpro” {

		  permission java.io.FilePermission "/tmp", "read";
		  permission java.net.SocketPermission "*", "connect";
		 };
		

Creare un certificato

Il primo passo indispensabile per firmare del codice è procurarsi un certificato.

Il certificato ideale è rilasciato da un’autorità di certificazione che goda la fiducia degli utenti del programma.

Al momento di eseguire il codice, la macchina virtuale Java rileva la firma e la verifica. Poniamo che il certificato annesso al codice contenga l’asserzione che l’identità del firmatario è Michele Costabile. Come in ogni documento di identità ci sarà un riferimento a un ente che certifica che l’affermazione è veritiera, che nel caso di una comune carta di identità è il comune che l’ha emessa.

Nel caso di un certificato digitale, l’ente che emette il certificato potrebbe essere, poniamo, Verisign. Il codice dal lato client può verificare questa asserzione e contattare via Internet Verisign per verificare che il certificato non sia stato ritirato, ad esempio, per il furto del computer su cui era installato il certificato del firmatario. Dopo questa verifica, se Verisign è una delle società di certificazione di cui il computer dell’utente si fida, il certificato è controllato e l’identità di chi lo ha emesso è considerata verificata.

Naturalmente, un certificato ufficiale costa. L’alternativa a costo zero è l’autocertificazione, cioè il certificato self signed. Se un utente si collega al sito della XYZ Spa, per esempio, si fiderà di un’applet firmata dalla XYZ, con un certificato garantito dalla XYZ.

Per creare un certificato, apriamo una finestra di comando, assicuriamoci di avere nel path la directory bin del kit di sviluppo java, nel nostro caso C:\Programmi\Java\jdk1.5.0_02\bin e lanciamo il programma keytool con le opzioni –genkey, -alias pcpro, -keyalg rsa e, volendo impostiamo una validità in giorni, per esempio –validity 365.

La sessione sarà interattiva e dovremo specificare il nome e cognome, l’unità organizzativa, l’azienda e i dati geografici tipici di un identificativo X.500, come quelli di una directory Ldap.

Ecco un esempio:

C:\security> keytool -genkey -alias
pcpro -keyalg rsa -validity 365
Immettere la password del keystore: changeit
Specificare nome e cognome
[Unknown]: Michele Costabile
Specificare il nome dell'unità aziendale
[Unknown]: Redazione
Specificare il nome dell'azienda
[Unknown]: PC Professionale
Specificare la località
[Unknown]: Milano
Specificare la provincia
[Unknown]: MI
Specificare il codice a due lettere del paese in cui si trova l'unità
[Unknown]: IT
Il dato CN=Michele Costabile, OU=Redazione, O=PC Professionale, L=Milano, ST=MI,
C=IT è corretto?
[no]: si
Immettere la password della chiave per <pcpro>
(INVIO se corrisponde alla password del keystore):

Abbiamo creato il nostro certificato, adesso possiamo verificarne il contenuto, sempre con il comando keytool

D:\Home> keytool -printcert -file pcpro.cer
Proprietario: CN=Michele Costabile, OU=Redazione, O=PC Professionale, L=Milano,
ST=MI, C=IT
Organismo di emissione: CN=Michele Costabile, OU=Redazione, O=PC Professionale,
L=Milano, ST=MI, C=IT
Numero di serie: 42668620
Valido da Wed Apr 20 18:41:04 CEST 2005 a Thu Apr 20 18:41:04 CEST 2006
Impronte digitali certificato:
MD5: B4:51:82:65:67:02:7B:2C:79:99:35:7A:CD:CC:4B:0C
SHA1: 3D:AF:91:97:1F:54:E5:5B:5E:8E:E6:C6:6D:F4:DA:CE:48:0E:3F:4F

Possiamo anche esportare il certificato in un file. Questo è utile per permettere a eventuali clienti di scaricare il certificato e installarlo in modo da dare un’autorizzazione preventiva permanente al codice firmato con quel certificato.

C:\security> keytool -export -alias
pcpro -file pcpro.cer
Immettere la password del keystore: changeit
Il certificato è memorizzato nel file <pcpro.cer>

Firma dell’applet

Per firmare un’applet occorre confezionarla in un archivio Jar e firmare l’archivio con il programma jarsigner.

Il comando jarsigner richiede, nella forma più semplice, solo due parametri: il nome dell’archivio da firmare e l’alias del certificato digitale conservato nell’archivio dei certificati. Quando abbiamo usato il programma keytool per creare il certificato abbiamo usato l’opzione -alias per assegnare il nome breve pcpro al certificato, quindi la riga di comando di jarsigner sarà

C:security> jarsigner runfile.jar pcpro
Enter Passphrase for keystore: changeit
Dopo l'operazione di firma, proviamo a elencare il contenuto dell'archivio Jar con il comando
jar tvf runfile.jar

troveremo due nuovi file: PCPRO.SF e PCPRO.RSA. Un archivio Jar potrebbe essere firmato anche da più soggetti. Per ogni soggetto che firma l’archivio troveremo una coppia di file con suffisso SF e RSA. La correttezza della firma di un archivio jar si può verificare con

jarsigner -verify runfile.jar.

Esecuzione dell’applet firmata

Modifichiamo la pagina Html che ospita l’applet per fare riferimento all’archivio Jar. Cambiamo il tag applet nel modo seguente:

<applet codebase=”.”

  archive="runfile.jar"
  code="RunFile"
  width="1024" height="50">

L’attributo code contiene il nome della classe e l’attributo archive il nome dell’archivio in cui è contenuta. Aprendo la pagina Html, anche dal disco locale, avremo una segnalazione che riguarda il certificato, che è self signed. Se decidiamo di fidarci del certificato si aprirà la finestra del notepad, se neghiamo la fiducia all’applet vedremo la segnalazione dell’errore nella pagina del browser. Una volta accordata la fiducia, il codice andrà in esecuzione direttamente per tutta la durata della sessione. Se si chiude il browser, o si apre la pagina con un browser diverso, avremo nuovamente la segnalazione. Naturalmente, abbiamo la possibilità di concedere fiducia in modo permanente al codice firmato, salvo revocarla in seguito.

Gestione dei certificati

Se nella finestra di dialogo della protezione rispondiamo alla richiesta di accettare il certificato con un clic sul pulsante Sempre, il certificato sarà scritto su disco e conservato in modo da non dovere più ripetere l’autorizzazione. Naturalmente, la decisione non è senza ritorno. Il pannello di controllo di Java consente di visualizzare i certificati memorizzati su disco e di cancellare quelli che non si ritiene opportuno conservare. Per avviare il pannello di controllo bisogna fare clic sulla familiare icona della tazza di caffé nel pannello di controllo di Windows, o sulla barra delle applicazioni di Windows, che mostra l’icona di controllo di Java durante l’esecuzione di un’applet. Facendo un clic sulla scheda Protezione e sul pulsante Certificati, possiamo visualizzare l’elenco dei certificati accettati in modo permanente. Selezionando uno dei certificati possiamo visualizzare il contenuto dell’attestazione di identità, esportarlo nel file system, per esempio per copiarlo su un supporto rimuovibile e installarlo su un altreo computer e infine possiamo eliminare la registrazione permanente del certificato. Ovviamente, togliamo ogni diritto speciale alle applet firmate con un determinato certificato rimuovendolo dal database locale. Se nella lista dei certificati attiviamo la scheda Sistema e scegliamo CA Firmataria dall’elenco a discesa, vedremo una lunga lista di certificati che il sistema considera affidabili. I certificati che si appoggiano a uno dei certificati radice saranno considerati attendibili dal sistema, essendo garantiti da un’autorità a cui è stata concessa fiducia.

Reblog this post [with Zemanta]

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...