Introduzione
Il problema
Supponiamo di voler sviluppare un applet di nome myapplet che scriva un messaggio in un file la cui path gli è passata come parametro. Per fare questo, inseriamo all’interno del metodo init() le seguenti istruzioni :
...
try
{
iDataOutputStream=new DataOutputStream(new BufferedOutputStream ( new FileOutputStream(path))) ;
iDataOutputStream.writeChars(“Ciao, questo è un applet che scrive in un file”) ;
iDataOutputStream.flush() ;
}
catch (SecurityException e)
{
System.out.println(e.getMessage()) ;
...
}
catch (IOException e)
{
System.out.println(e.getMessage()) ;
...
}
...
Per default, tale applet non può accedere alle risorse di un sistema al di fuori della directory da cui è stato scaricato, pertanto non appena andremo ad eseguirlo con un browser java-enabled (Netscape Comunicator, Internet Explorer o altri) avremo una Security Exception. Di contro, è possibile estendere le autorizzazioni di sicurezza di un applet rendendolo signed (firmato). In questo modo, quest’ultimo potrà accedere alle risorse di una macchina client con le autorizzazioni che gli verranno assegnate da un sistema di Security Policy.
Il JDK 1.2 mette a disposizione dei tools di security che consentono agli utenti finali e/o amministratori di firmare applet (ma anche applicazioni) e di definire la Security Policy relativa a tale applet e/o applicazione specificando le permission in un apposito Policy file.
Come rendere un applet “signed”
Pre-requisito per poter firmare e quindi manipolare signed applet è quello di inserire questi ultimi all’interno di Java ARchive (JAR). Quindi, all’interno della pagine HTML che dovrà contenere (ad esempio) myapplet inseriremo un applet tag del tipo :
<applet code="myapplet.class" archive="smyapplet.jar" width="400" height="400"> <param name="file" value="user\home\myfile.msg"> </applet>
Esaminiamo ora le attività da svolgere per firmare un applet e fare in modo che questo funzioni correttamente sulla macchina client, il che significa mettere quest’ultima nelle condizioni di verificare chi è il “firmatario” dell’applet che ha scaricato e in base a questo assegnare le dovute autorizzazioni per l’accesso alle risorse della macchina \[1\].
Per firmare un applet, attività che riguarda chi lo sviluppa e/o lo rende disponibile, le attività da svolgere sono le seguenti :
Compilazione
javac myapplet.java
Creazione del file JAR
jar -cvf myapplet.jar myapplet.class \*.gif
Ricordiamo che il Java ARchive è un formato compresso\[2\] che consente di scaricare i un’unica sessione dal server le classi necessarie per far funzionare l’applet e le risorse che quest’ultimo utilizza (es. immagini, suoni, ecc.). In questo caso il tool jar viene utilizzato con le opzioni -cvf che significano : creazione di un nuovo archivio, modalità verbose e inserimento del nome dell’archivio da creare.
Generazione delle chiavi (pubblica e privata)
A questo punto, è necessario generare due chiavi asimmetriche che utilizzeremo rispettivamente per firmare l’applet (privata) e per consentire alla macchina client di verificare la firma digitale (pubblica)\[1\]. Quest’ultima sarà distribuita attraverso un certificato reso disponibile a tutti gli utilizzatori finali dell’applet.
Il comando per effettuare questa operazione è il seguente :
keytool -genkey -alias signapplet -keystore mystore -keypass kpi135 -dname “cn=cnapplet” -storepass abcd00
Con il tool keytool, ed in particolare con l’opzione -genkey viene generata una coppia di chiavi identificata attraverso l’alias signapplet. Tale alias, sarà utilizzato insieme alla password kpi135 specificata con l’opzione -keypass per poter accedere alla chiave privata in successive invocazioni dei tools di security. La coppia di chiavi generata viene quindi memorizzata in un keystore di nome mystore che si trova nella directory dal quale è stato lanciato il comando e al quale si accede attraverso la password abcd00 Infine con l’opzione -dname e “cn=cbapplet”, viene specificato un X.500 Distinguished Name (con common name cbapplet) per identificare un istanza del certificato X.509.
Firma dell’archivio
Dopo la generazione delle chiavi, attraverso il tool jarsigner, si può procede alla firma dell’archivio che contiene l’applet :
jarsigner -keystore mystore -storepass abcd00 -keypass kpi135 -signedjar smyapplet.jar myapplet.jar signapplet
Con questo comando, attraverso la chiave signapplet (alias precedentemente specificato) contenuta nel keystore mystore si firma l’archivio myapplet.jar ottenendo così smyapplet.jar.
Esportazione del certificato
Per poter distribuire la chiave pubblica agli utenti finali che la utilizzeranno per verificare l’applet, si effettua l’export del certificato nel seguente modo:
keytool -export -keystore mystore -storepass abcd00 -alias signapplet -file signapplet.cer
In questo caso, il certificato viene memorizzato nel file signapplet.cer.
Quelle viste fino ad ora sono le operazioni necessarie poter per firmare l’applet e distribuire, attraverso un apposito certificato (signapplet.cer) la chiave pubblica agli utenti finali dell’applicazione. Analizziamo ora in dettaglio le operazioni che devono effettuare da questi ultimi sulla macchina client per poter estendere le autorizzazioni di default assegnate all’applet :
Importazione del certificato
keytool -import -alias csignapplet -file signapplet.cer -keystore cmystore -storepass abcdef
In questo modo, il certificato viene importato nel keystore cmystore con alias csignapplet.
Creazione del policy file
Dopo aver importato il certificato, in un Policy file (Write.jp) e per ognuna delle risorse che saranno utilizzate, verranno definite le permission di accesso degli applets firmati da uno specifico signer :
keystore “file :/d :/Tests/cmystore” ;
// esempio di Policy file
grant SignedBy “csignapplet” {
permission java.util.PropertyPermission “user.home”,”read”
permission java.util.FilePermission “\${user.home}/myfile.msg”,”write”
} ;
Con il policy file di sopra, viene data la possibilità a tutti gli applets firmati da csignapplet di scrivere in un file myfile.msg che si trova sotto la home directory dell’utente e di poter comporre dinamicamente la path di tale file leggendo la proprietà user.home.
Queste ultime due operazione (quelle effettuate sulla macchina client) sono valide se si esegue l’applet con l’appletviewer nel seguente modo :
appletview -J-Djava.security.policy=Write.jp http ://myweb.com/myapplet.html
Viceversa, nel caso in cui l’esecuzione dell’applet deve avvenire all’interno di un browser, le operazioni di import del certificato e di definizione delle permission sulle risorse del sistema dovranno essere effettuate con le funzionalità messe a disposizione dal medesimo browser. In particolare, nel caso in cui si utilizza IE le cose si complicano un po’ visto che tale browser riconosce CAB firmati con le CryptoAPI attraverso il tool sign.exe invece di JAR. Ovviamente, un pre-requisito a tutto questo è che i browser in questione supportino direttamente o indirettamente (Project Java Activator) la piattaforma Java 2.
Configurazione del Security Manager e utilizzo del Policy Tool
Gli errori più frequenti che si commettono quando si utilizzano i signed applets sono quelli derivanti da una scorretta configurazione del Security Manager. Al fine di evitare tali problemi, vediamo brevemente quali sono le modalità per una corretta configurazione del sistema di sicurezza. Innanzitutto, diciamo che i policy files che vengono valutati dal security manager quando si esegue un applet e/o un applicazione signed, sono quelli elencati nel seguente file (java.home è la directory nella quale è installata la VM) :
java.home\lib\security\java.security
L’elenco dei policy files all’interno di tale file va specificato nella seguente forma
policy.URL.<i>=<url>
Ad esempio, potremo avere :
policy.url.1=\$(java.home)/lib/security/java.policy policy.url.2=\$(user.home)/.java.policy policy.url.3=\$(user.home)/write.jp
I primi due sono rispettivamente il policy file di default del sistema e il policy file di default dell’utente, mentre la proprietà user.home assumerà a run-time uno dei seguenti valori a seconda della piattaforma sulla quale è in esecuzione la VM :
Piattaforma user.home
Windows NT C :\Winnt\Profiles\\user> Windows 95 multi-user C :\Windows\Profiles\\user> Windows 95 single-user C :\Windows
Quando si esegue un applicazione è inoltre possibile specificare un ulteriore policy file specificando l’argomento “-Djava.security.policy”. Ad esempio :
java -Djava.security.manager -Djava.security.policy=Altro.jp SomeApp
Per quanto riguarda la manipolazione dei police files, il JDK 1.2 mette a disposizione un tool (Policy Tool) che ne facilita la gestione. Tale tool può essere attivato con il comando policytool e la schermata inizialmente visualizzata dopo l’esecuzione del comando è la seguente :
Da questa finestra, sarà possibile aprire un file esistente oppure crearne uno nuovo specificandone la path. Inoltre, è possibile modificare il keystore a cui il file fa riferimento selezionando l’opzione “Change Keystore” dal menù “Edit”:
Il JKS specificato nel campo New KeyStore Type è un tipo proprietario supportato dalla Sun. Dopo aver modificato il keystore, è possibile aggiungere al file una policy entry cliccando sul tasto “Add Policy Entry” della finestra iniziale (sempre da questa finestra è possibile attivare le funzioni per rimuovere e modificare una entry). Nella finestra che viene visualizzata è possibile impostare due parametri (entrambi opzionali) che sono il codebase da dove viene scaricato l’applet e l’alias con il quale è stato firmato :
In questo caso, avendo impostato solo il codebase le permission che successivamente andremo ad impostare saranno valide per ogni applet scaricato da tale directory (sia esso firmato o non). Ovviamente, il codebase potrà essere (anzi lo è quasi sempre) del tipo : http : //www.myweb.com.
Infine, rimangono da definire le permission attraverso la selezione del tasto “Add Permission”:
In questo modo, abbiamo abilitato gli applets alla lettura del D:\Temp\mydata.
JDK 1.1
Con la seguente tabella, vediamo come le medesime operazioni (creazione JAR, generazione chiavi, firma, ecc.) possono o potranno (come preferite) essere realizzate nella precedente versione della piattaforma Java :
- Compilazione
javac myapplet.java
- Creazione JAR file
jar -cvf myapplet.jar myapplet.class \*.gif
- Generazione delle chiavi (pubblica e privata)
javakey -cs signapplet true
javakey -gk signapplet signappletpub signappletpriv
- Firma dell’archivio
javakey -gs dirsign myapplet.jar
Dove dirsign è un file di direttive del tipo :
\#esempio di un file di direttive per la firma di un archivio JAR
-signer=signapplet
-cert=1
-chain=0
-signature.file=sapplet
Dopo l’esecuzione del comando nel JAR sanno inclusi i seguenti files
-sapplet.sf
-sapplet.dsa
- Export del certificato
javakey -gc dircer
Dove dircer è un file di direttive del tipo:
\# esempio di un file di direttive per l’export del
\# certificatoissuer.name=signappletissuer.cert=1
subject.name=x
subject.real.name=xxxx
subject.org.unit=xxx
subject.org=org
subject.country=Italy
start.date=1 Apr 1999
end.date=31 Dec 2000
serial.number=0001
signature.algorithm=DSA
out.file= signapplet.cer
- Import del certificato sulla macchina client
javakey -c signappletjavakey -ic signapplet signapplet.cer
Bibliografia
- \
- [1\] A. Furome, Firma Digitale, Mokabyte, Ottobre 1999
- \
- [2\] H. Jubin, JavaBeans by Example, Prentice Hall, 1997
