From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100305.html | 849 +++++++++++++++++++++ 1 file changed, 849 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100305.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100305.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100305.html b/Master/Reference Architectures and Patterns/hjp5/html/k100305.html new file mode 100644 index 0000000..95a9fcd --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100305.html @@ -0,0 +1,849 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 48 - Sicherheit und Kryptographie +
+
+ + + + +

48.3 Signierte Applets

+
+ +
+ +

+In diesem Abschnitt wird beschrieben, wie einem Applet der Zugriff +auf geschützte Ressourcen gewährt werden kann. Wir gehen +dazu in folgenden Schritten vor: +

    +
  1. Zunächst wird ein Applet entwickelt, das auf einige beschränkte +Ressourcen zugreift. Ohne weitere Vorkehrungen ist es nicht lauffähig, +sondern wird mit einer SecurityException +abgebrochen. +
  2. Anschließend zeigen wir, wie das Applet mit Hilfe des in +Abschnitt 48.1.6 +erzeugten Schlüsselpaars signiert wird. +
  3. Danach demonstrieren wir die Weitergabe von Zertifikaten. +
  4. Schließlich zeigen wir, wie die Sicherheitseinstellungen +so angepasst werden, dass das Applet Zugriff auf die gewünschten +Ressourcen erhält. +
+ + + + +

48.3.1 Ein »unerlaubtes« Applet

+ +

+Wir wollen uns die Aufgabe stellen, ein Applet zu schreiben, das einige +Sicherheitsverstöße begeht. Zunächst soll es eine +Datei auf dem lokalen Computer erzeugen und einen Zeitstempel hineinschreiben. +Zusätzlich soll es auf einige geschützte System-Properties +zugreifen und deren Inhalt in die Datei schreiben. Das Applet hat +folgenden Aufbau: + + +

+ + + + + +
+ +
+001 /* TrustedApplet.java */
+002 
+003 import java.awt.*;
+004 import java.applet.*;
+005 import java.util.*;
+006 import java.io.*;
+007 
+008 public class TrustedApplet
+009 extends Applet
+010 {
+011   static final String ALLOWED_DIR = "c:\\tmp\\applets\\";
+012   static final String FNAME       = "TrustedApplet.log";
+013   static final String LOGMSG      = "Erzeugt von Applet: ";
+014   String msg;
+015 
+016   public void init()
+017   {
+018     msg = "Uninitialisiert";
+019     FileWriter out = null;
+020     try {
+021       //Ausgabedatei erzeugen
+022       out = new FileWriter(ALLOWED_DIR + FNAME);
+023       //Logmessage schreiben
+024       out.write(LOGMSG);
+025       //Zeitstempel schreiben
+026       GregorianCalendar cal = new GregorianCalendar();
+027       out.write(cal.get(Calendar.DATE) + ".");
+028       out.write((cal.get(Calendar.MONTH) + 1) + ".");
+029       out.write(cal.get(Calendar.YEAR) + " ");
+030       out.write(cal.get(Calendar.HOUR_OF_DAY) + ":");
+031       out.write(cal.get(Calendar.MINUTE) + ":");
+032       out.write(cal.get(Calendar.SECOND) + "");
+033       out.write(System.getProperty("line.separator"));
+034       //System-Properties lesen und in Datei schreiben
+035       out.write(getProp("user.name"));
+036       out.write(getProp("user.home"));
+037       out.write(getProp("user.dir"));
+038       //Datei schließen
+039       msg = "Alle Sicherheitshuerden ueberwunden!";
+040     } catch (Exception e) {
+041       msg = e.toString();
+042     } finally {
+043       if (out != null) {
+044         try {
+045           out.close();
+046         } catch (IOException e) {
+047           //silently ignore
+048         }
+049       }
+050     }
+051   }
+052 
+053   public void paint(Graphics g)
+054   {
+055     g.drawString(msg, 20, 20);
+056   }
+057 
+058   private String getProp(String prop)
+059   {
+060     return prop + "=" +
+061            System.getProperty(prop) +
+062            System.getProperty("line.separator");
+063   }
+064 }
+
+
+TrustedApplet.java
+ +Listing 48.7: Ein »unerlaubtes« Applet

+ +

+Es versucht zunächst eine Datei c:\tmp\applets\TrustedApplet.log +zu erzeugen. Wenn dies gelingt, instanziert es ein aktuelles GregorianCalendar-Objekt +und schreibt dessen Werte in die Datei. Schließlich versucht +es, die System-Properties »user.name«, »user.home« +und »user.dir« zu lesen und deren Werte ebenfalls in die +Datei zu schreiben. Sind all diese Versuche erfolgreich, gibt das +Applet die Meldung »Alle Sicherheitshuerden ueberwunden!« +aus. Tritt eine Ausnahme auf, wird deren Text ausgegeben. +

+ + + + + + + + + +
+ +

+Um das Schreiben der Datei zu ermöglichen, ist ein Verzeichnis +c:\tmp\applets anzulegen. Andernfalls +gibt es eine IOException +- selbst wenn alle Sicherheitshürden genommen sind.

+ + + + +
 Hinweis 
+
+ +

+Das Applet kann mit folgender HTML-Datei gestartet werden: + + +

+ + + + +
+ +
+001 <html>
+002 <head>
+003 <title>TrustedApplet Demo</title>
+004 </head>
+005 
+006 <body>
+007 <h1>TrustedApplet Demo</h1>
+008 
+009 <applet
+010   code="TrustedApplet.class"
+011   width=600
+012   height=200
+013 >
+014 TrustedApplet Demo
+015 </applet>
+016 
+017 </body>
+018 </html>
+
+
+ +Listing 48.8: Vorläufige HTML-Datei zum Aufruf des unerlaubten +Applets

+ +

+Das Applet kann nun beispielsweise mit dem appletviewer +gestartet werden: + +

+appletviewer TrustedApplet.html
+
+ + +

+Wird es ohne weitere Vorkehrungen gestartet, scheitert es bereits +am Erzeugen der Ausgabedatei und gibt eine SecurityException +auf dem Bildschirm aus. + + + + +

48.3.2 Signieren des Applets

+ +

+Zum Signieren ist es zunächst erforderlich, alle für den +Betrieb des Applets nötigen Dateien in ein jar-File zu packen. +Signiert wird also nicht eine einzelne .class-Datei, +sondern alle Dateien innerhalb des jar-Archivs. Dazu verwenden wir +folgendes Kommando: + +

+jar cvf trapp.jar TrustedApplet.class
+
+ + +

+Jetzt wird ein jar-Archiv trapp.jar erstellt, +das die Klassendatei TrustedApplet.class +enthält. Dieses Archiv muss nun signiert werden. Dazu steht im +JDK das Hilfsprogramm jarsigner +zur Verfügung. Es arbeitet kommandozeilenbasiert und wird folgendermaßen +aufgerufen: +

+ + + + +
+ +
+jarsigner -signedjar outjar injar alias
+
+
+
+ +

+Die einzelnen Elemente haben folgende Bedeutung: +

+ +

+Nachdem wir in Abschnitt 48.1.6 +bereits ein Schlüsselpaar mit dem Alias »hjp3« erzeugt +und in der Schlüsseldatenbank abgelegt haben, muss der Aufruf +von jarsigner +so erfolgen: + +

+C:\--->jarsigner -signedjar strapp.jar trapp.jar hjp3
+Enter Passphrase for keystore: hjp3ks
+Enter key password for hjp3: hjp3key
+
+ + +

+Die beiden Paßwörter zum Zugriff auf die Schlüsseldatenbank +und den Schlüssel werden auf Nachfrage in der Kommandozeile angegeben. +Nachdem das Programm einige Zeit gerechnet hat, erzeugt es das signierte +Archiv mit dem Namen strapp.jar. +

+ + + + + + + + + +
+ +

+jarsigner +bietet neben den hier erwähnten noch weitere Optionen, auf die +wir nicht weiter eingehen wollen. Das Programm wird zusammen mit den +anderen Hilfsprogrammen in der Tool-Dokumentation des JDK ausführlich +beschrieben.

+ + + + +
 Hinweis 
+
+ +

+Bisher wurde das Applet direkt aus der .class-Datei +geladen. Um es aus einem jar-Archiv zu laden, muss das APPLET-Tag +der HTML-Datei um das archive-Argument +erweitert werden: + + +

+ + + + + +
+ +
+001 <-- TrustedApplet.html -->
+002 
+003 <html>
+004 <head>
+005 <title>TrustedApplet Demo</title>
+006 </head>
+007 
+008 <body>
+009 <h1>TrustedApplet Demo</h1>
+010 
+011 <applet
+012   archive="strapp.jar"
+013   code="TrustedApplet.class"
+014   width=600
+015   height=200
+016 >
+017 TrustedApplet Demo
+018 </applet>
+019 
+020 </body>
+021 </html>
+
+
+TrustedApplet.html
+ +Listing 48.9: Aufruf des signierten Applets

+

+ + + + + + + + + +
+ +

+Wir könnten das Applet jetzt wie zuvor starten, würden aber +immer noch dieselbe SecurityException +erhalten. Es ist zwar signiert und das Zertifikat ist auf diesem Rechner +bekannt (denn hier wurde es erstellt). Die Policy-Datei ist aber noch +nicht angepasst, und daher lehnt der SecurityManager +des JDK die Ausführung der gefährlichen Operationen nach +wie vor ab.

+ + + + +
 Hinweis 
+
+ + + + +

48.3.3 Ex- und Import von Zertifikaten

+ +

+Soll das signierte Applet auf anderen Arbeitsplätzen laufen, +ist es erforderlich, das Zertifikat des Schlüssels, mit dem es +signiert wurde, dort zu installieren. Soll es dagegen nur auf dem +Arbeitsplatz laufen, auf dem auch der Schlüssel generiert wurde, +ist das nicht erforderlich. Bei der Generierung des Schlüssels +wurde ja auch ein (selbstsigniertes) Zertifikat erzeugt. + +

+Um das Zertifikat weitergeben zu können, muss es zunächst +unter Verwendung der Option -export +von keytool +aus der lokalen Schlüsseldatenbank exportiert werden: + +

+keytool -export -alias hjp3 -file hjp3.cert
+
+ + +

+Es liegt nun in der Datei hjp3.cert und +kann auf das Zielsystem kopiert werden. Mit der -import-Option +von keytool +kann es dort in die Schlüsseldatenbank aufgenommen werden: + +

+C:\--->keytool -import -alias hjp3 -file hjp3.cert
+Enter keystore password:  hjp3ks
+Owner: CN=Guido Krueger, O=Computer Books, C=de
+Issuer: CN=Guido Krueger, O=Computer Books, C=de
+Serial number: 38663e2d
+Valid from: Sun Dec 26 17:11:25 GMT+01:00 1999 until: Sat Mar 25 17:11:25 GMT+01
+:00 2000
+Certificate fingerprints:
+         MD5:  D5:73:AB:06:25:16:7F:36:27:DF:CF:9D:C9:DE:AD:35
+         SHA1: E0:A4:39:65:60:06:48:61:82:5E:8C:47:8A:2B:04:A4:6D:43:56:05
+Trust this certificate? [no]:  y
+Certificate was added to keystore
+
+ + +

+Nach dem Aufruf muss zunächst das Paßwort der Schlüsseldatenbank +angegeben werden. Dann zeigt das Programm die Eigenschaften des Zertifikats +an und erwartet, dass die Informationen bestätigt werden. Anschließend +wird das Zertifikat in die Schlüsseldatenbank aufgenommen. + + + + +

48.3.4 Anpassen der Policy-Datei

+ + + + +

Policy-Dateien

+ +

+Der letzte Schritt besteht darin, die Sicherheitseinstellungen auf +dem Zielsystem anzupassen. Applets, die mit dem Zertifikat verifiziert +werden können, das unter dem Alias »hjp3« in der Schlüsseldatenbank +abgelegt wurde, sollen Dateien im Verzeichnis c:\tmp\applets +lesen und schreiben und auf die System-Properties »user.name«, +»user.home« und »user.dir« zugreifen können. + +

+Die Sicherheitseinstellungen des JDK werden mit Hilfe von Policy-Dateien +definiert. Es gibt zwei Stellen im Dateisystem, von denen das JDK +sie standardmäßig einliest: +

+

+ + + + + + + + + + + +
+ +

+Policy-Dateien können auch an beliebigen anderen Stellen im Dateisystem +liegen. In diesem Fall muss beim Aufruf des Java-Interpreters das +System-Property »java.security.policy« mit dem Namen der +zu verwendenen Policy-Datei angegeben werden. Wäre beispielsweise +hjp3policy die zu verwendende Policy-Datei, +so müsste der Appletviewer mit der Option »-J-Djava.security.policy=hjp3policy« +aufgerufen werden.

+ + + + +
 Tipp 
+
+ + + + +

Das Format einer Policy-Datei

+ +

+Policy-Dateien sind zeilenorientierte Textdateien, die mit einem gewöhnlichen +Texteditor bearbeitet werden können. Alternativ stellt das JDK +ein einfaches GUI-basiertes Hilfsprogramm mit dem Namen policytool +zur Verfügung, mit dem Policy-Dateien erstellt und bearbeitet +werden können. Auf seine Verwendung wollen wir aber nicht weiter +eingehen. + +

+Eine Policy-Datei enthält zwei Arten von Einträgen. Beide +sind optional: +

+ +

+Alle Einträge werden mit einem Semikolon beendet. Kommentare +können an beliebiger Stelle durch // oder /* ... */ angelegt +werden. + +

+Der »keystore«-Eintrag erwartet als Argument einen URL, +der auf die Schlüsseldatenbank verweist. Auf einem Windows-98-Einzelplatzsystem +sieht er beispielsweise so aus: + +

+keystore "file:/c:/windows/.keystore";
+
+ + +

+Die »grant«-Einträge haben folgende Syntax: +

+ + + + +
+ +
+grant [SignedBy "signer"] [, CodeBase "URL"] {
+  permission permission_class [ "target" ] [, "action"]
+             [, SignedBy "signers"];
+  ...
+};
+
+
+
+ +

+Eine Berechtigung kann wahlweise an einen Unterzeichner oder eine +Ladeadresse (oder beide) vergeben werden. Die Option »SignedBy« +führt eine Liste von Aliasnamen auf, deren Zertifikate vorhanden +sein müssen, damit die Berechtigung gewährt wird. Die Option +»CodeBase« spezifiziert die Adresse, von der ein Applet +geladen werden darf, um die Berechtigung zu halten. Fehlt die CodeBase-Klausel, +wird nur die Unterzeichnerliste verwendet; fehlt die SignedBy-Klausel, +ist es nur die Ladeadresse. + +

+Nach einer öffnenden geschweiften Klammer folgen beliebig viele +Berechtigungen, die jeweils durch das Schlüsselwort »permission« +eingeleitet werden. Anschließend wird der Eintrag mit einer +schließenden geschweiften Klammer abgeschlossen. Der zuvor spezifizierte +Berechtigte erhält alle Berechtigungen, die zwischen den beiden +Klammern angegeben sind. + +

+Jede Berechtigung muss als erstes Argument den Namen einer Berechtigungsklasse +angeben. Daneben kann sie zwei weitere Argumente target und +action haben, mit denen Details spezifiziert werden. Tabelle 48.1 +listet die gebräuchlichsten Berechtigungen und ihre Argumente +auf. Details können (und müssen) in dem Dokument »Java +Security Architecture« nachgelesen werden, das Bestandteil der +JDK-Dokumentation ist. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KlasseZugriff aufTargetAction
java.io.FilePermissionDateien und VerzeichnisseDatei- oder Verzeichnisnamen. Wird als letztes +Zeichen ein »*« angegeben, so gilt die Berechtigung für +das komplette Verzeichnis. Steht dort ein »-«, so gilt sie +zusätzlich für alle Unterverzeichnisse. Wird »<<ALL +FILES>>« angegeben, gilt die Berechtigung für alle +Dateien in allen Verzeichnissen!read, write, delete, execute
java.net.SocketPermissionTCP/IP-VerbindungenHostname oder IP-Adresse, gefolgt von Portnummern-Bereichaccept, connect, listen, resolve
java.util.PropertyPermissionSystem-PropertiesNames des Propertiesread, write
java.lang.RuntimePermission Die Klasse RuntimeexitVM, stopThread, loadLibrary, queuePrintJob, +...-
java.awt.AWTPermissionWindow-RessourcenaccessClipboard, showWindowWithoutWarningBanner, +...-
java.security.AllPermissionAlle Ressourcen--
+

+Tabelle 48.1: Wichtige Permission-Klassen

+ + + + +

Erstellen der Policy-Datei

+ +

+Nach diesen Vorbemerkungen können wir die Policy-Datei \windows\.java.policy +erstellen. Sie hat folgenden Inhalt: + +

+keystore "file:/c:/windows/.keystore";
+
+grant SignedBy "hjp3" {
+  permission java.io.FilePermission "c:\\tmp\\applets\\*", "read,write";
+
+  permission java.util.PropertyPermission "user.name", "read";
+  permission java.util.PropertyPermission "user.home", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+};
+
+ + +

+Im ersten Eintrag geben wir die Position der Schlüsseldatenbank +an, sie liegt im Verzeichnis c:\windows. +Anschließend definieren wir die Berechtigungen für alle +Applets, die mit dem Zertifikat »hjp3« signiert wurden. +Zunächst erhalten sie Schreib- und Leseberechtigung im Verzeichnis +c:\tmp\applets. Dort können sie +ohne weitere Einschränkungen Dateien anlegen, überschreiben +und lesen. Zusätzlich erlauben wir den so signierten Applets, +die drei System-Properties »user.name«, »user.home« +und »user.dir« zu lesen. + +

+Nun läßt sich unser signiertes Applet ohne SecurityException +aufrufen und gibt die erlösende Meldung »Alle Sicherheitshuerden +ueberwunden« aus. Im Verzeichnis c:\tmp\applets +sollte sich anschließend eine Datei TrustedApplet.log +befinden und etwa folgenden Inhalt haben: + +

+Erzeugt von Applet: 30.12.1999 20:50:40
+user.name=Guido Krüger
+user.home=C:\WINDOWS
+user.dir=C:\arc\doku\hjp3\misc
+
+ + + + + +

48.3.5 Die Klasse SecurityManager

+ +

+Die Prüfung der Zugriffsberechtigungen wird mit Hilfe der Klasse +SecurityManager +aus dem Paket java.lang +vorgenommen. Der SecurityManager +ist ein Objekt, das entweder gar nicht oder genau einmal im laufenden +Java-Programm vorhanden ist. Nach der ersten Instanzierung kann es +nicht mehr geändert oder entfernt werden. + +

+Zugriffe auf den SecurityManager +sind an den Stellen der Laufzeitbibliothek eingebaut, an denen auf +gefährliche Ressourcen zugegriffen wird. Ein Beispiel aus der +Klasse FileInputStream +sieht etwa so aus: + +

+...
+SecurityManager security = System.getSecurityManager();
+if (security != null) {
+  security.checkRead(name);
+}
+//Gefährlicher Code
+...
+
+ + +

+Zunächst wird geprüft, ob ein SecurityManager +installiert wurde. Ist das nicht der Fall, fährt das Programm +ohne Einschränkung fort. Gibt es dagegen einen SecurityManager, +wird dessen checkRead-Methode +aufgerufen. Sie löst eine SecurityException +aus, wenn die gewünschte Berechtigung fehlt. Der Code hinter +dem checkRead +wird in diesem Fall nicht mehr erreicht. Ist die Berechtigung dagegen +vorhanden, wird checkRead +ohne weitere Aktionen beendet und der dahinter liegende Code ausgeführt. + +

+Applets besitzen grundsätzlich einen SecurityManager. +Der AppletViewer bzw. Web-Browser sorgen während der Initialisierung +für dessen Instanzierung. Applikationen dagegen haben normalerweise +keinen SecurityManager +(das ist der Grund, weshalb in Applikationen alle gefährlichen +Operationen erlaubt sind). Soll eine Applikation einen SecurityManager +erhalten, so kann sie entweder mit der Option »-Djava.security.manager« +gestartet werden, oder der SecurityManager +kann im Programm selbst installiert werden: + +

+...
+System.setSecurityManager(new SecurityManager());
+...
+
+ + +

+Das folgende Beispielprogramm gibt den Inhalt des System-Properties +»user.name« aus. Normalerweise kann es ohne Fehler ausgeführt +werden: + + +

+ + + + + +
+ +
+001 /* SecuMgrTest.java */
+002 
+003 public class SecuMgrTest
+004 {
+005   public static void main(String[] args)
+006   {
+007     System.out.println(
+008       "user.name is " + System.getProperty("user.name")
+009     );
+010   }
+011 }
+
+
+SecuMgrTest.java
+ +Listing 48.10: Ausgeben des System-Properties »user.name«

+ +

+Läuft es dagegen unter Kontrolle eines SecurityManagers, so führt +der Aufruf zu einer SecurityException: + +

+C:\--->java -Djava.security.manager SecuMgrTest
+Exception in thread "main"
+  java.security.AccessControlException: access denied
+  (java.util.PropertyPermission user.name read)
+        at java.security.AccessControlContext.checkPermission(
+          AccessControlContext.java:276)
+        at java.security.AccessController.checkPermission(
+          AccessController.java:403)
+        at java.lang.SecurityManager.checkPermission(
+          SecurityManager.java:549)
+        at java.lang.SecurityManager.checkPropertyAccess(
+          SecurityManager.java:1242)
+        at java.lang.System.getProperty(System.java:555)
+        at Test1.main(SecuMgrTest.java:7)
+
+ + +

+Bei Bedarf kann man Applikationen auf diese Weise mit denselben Sicherheitsmechanismen +ausstatten wie Applets. jar-Dateien, aus denen Applikationen geladen +werden, lassen sich ebenso signieren wie solche, aus denen Applets +geladen werden. Die in der Policy-Datei definierten Rechte gelten +dann für die daraus gestartete Applikation. +


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3