Praktische Experimente mit OpenSSL
genutzte OpenSSL-Version: 0.9.5a
URLs:
- OpenSSL: http://www.openssl.org/
- OpenSSL-Handbuch:
http://www.pca.dfn.de/dfnpca/certify/ssl/handbuch/
- SSL-MZtelnet:
ftp://ftp.uni-mainz.de/pub/internet/security/ssl/SSL-MZapps/
- Netscape-Mirror an TUC:
ftp://ftp.tu-chemnitz.de/pub/network/www/netscape/
- Fortify:
- Stunnel:
- Apache und mod_ssl:
neue Test-CA erzeugen (mit selbstzertifziertem Zertifikat)
/usr/local/openssl/misc/CA.sh -newcaBei Verwendung der Standard-Einstellungen in /usr/local/openssl/openssl.cnf wird ein Verzeichnis demoCA erstellt, in dem u.a. folgende Informationen zu finden sind:
Das hier und nachfolgend genutzte Skript CA.sh dient der Vereinfachung einiger typischer OpenSSL-Operationen, indem es die jeweils benötigten OpenSSL-Kommandos mit geeigneten Argumenten aufruft.
private/cakey.pem privater Schlüssel der CA cacert.pem selbstzertifziertes Zertifikat der CA index.txt Liste der bereits ausgestellten Zertifikate serial Seriennummer für das nächste Zertifikat newcerts Verzeichnis für erstellte Zertifikate
neuen Schlüssel sowie Zertifikatsanforderung erstellen
/usr/local/openssl/misc/CA.sh -newreqDiese Kommando ist auf der Ebene des Elternverzeichnisses von demoCA auszuführen.
Resultat: newreq.pem
Diese Datei sollte gut aufgehoben werden, da sie neben der Zertifikatsanforderung auch den neu generierten privaten Schlüssel enthält.
Zertifikat erstellen (Zertifikatsanforderung signieren)
/usr/local/openssl/misc/CA.sh -signDiese Kommando ist auf der Ebene des Elternverzeichnisses von demoCA auszuführen. Die Zertifikatsanforderung wird in der Datei newreq.pem erwartet.
Resultat: newcert.pem
Empfehlung: Zertifikatsanforderung (mit privatem Schlüssel) sowie Zertifikat umbenennen und aufheben, z.B.:
cp newreq.pem HINZ/hinz_req.pem cp newcert.pem HINZ/hinz_cert.pem
Zertifikat verifizieren
/usr/local/openssl/misc/CA.sh -verifyDiese Kommando ist auf der Ebene des Elternverzeichnisses von demoCA auszuführen und verifiziert das Zertifikat in der Datei newcert.pem.
Beispiel:
/usr/local/ssl/misc/CA.sh -verify newcert.pem: OK
Anzeige, Verifikation, Hash-Links
-
Schlüssel anzeigen:
openssl rsa -text -noout -in newreq.pem
-
Zertifikatsanforderung anzeigen:
openssl req -text -noout -in newreq.pem
-
Zertifikat anzeigen:
openssl x509 -text -noout -in newcert.pem
-
Fingerprint des Zertifikats berechnen:
openssl x509 -fingerprint -noout -in newcert.pem
-
Verifikation des Zertifikats:
openssl verify -CAfile demoCA/cacert.pem newcert.pem
-
Hash-Wert eines Zertifikats bestimmen und Link legen:
ln -s newcert.pem `openssl x509 -noout -hash -in newcert.pem`.0
Über einen solchen Link greifen die X.509-Verifikationsroutinen auf die Zertifikatsdateien zu. So nutzt z.B. der Apache mit mod_ssl im Rahmen der Überprüfung der zu einem Klienten-Zertifikat gehörenden Zertifikatskette solche Links für den Zugriff auf die einzelnen Zertifikatsdateien, die jeweils ein Zertifikat für den öffentlichen Schlüssel einer CA enthalten.Der Hashwert wird von der Komponente Subject eines Zertifikats gebildet. Unterschiedliche Zertifikate mit demselben Subject haben folglich denselben Hashwert. Anmerkung: Das Skript /usr/local/openssl/bin/c_rehash kann für die automatische Aktualisierung der Hash-Links aller Zertifikate in bestimmten Verzeichnissen genutzt werden.
Beispiel:
/usr/local/openssl/bin/c_rehash .
Dadurch werden für alle Dateien *.pem im aktuellen Verzeichnis neue Hash-Links erstellt.
Schlüssel und Zertifikat für SSL-Server (z.B. Apache) erstellen
-
Generierung eines RSA-Schlüssels ohne Paßwortschutz (für Server-Betrieb
sinnvoll):
openssl genrsa -out kirke_key 1024
-
selbstzertifiziertes Zertifikat für diesen privaten Schlüssel erstellen
(anstelle einer neuen Zertifikatsanforderung an die CA):
openssl req -new -days 365 -x509 -out kirke_self_cert -key kirke_key
-
neue Zertifikatsanforderung an die CA erstellen:
openssl req -new -out kirke_req -key kirke_key
-
Zertifikatsanforderung durch CA signieren und so das Zertifikat erstellen:
openssl ca -policy policy_anything -days 500 -out kirke_cert -infiles kirke_req
Durch die Option -days kann man die Gültigkeitsdauer des Zertifikats in Tagen festlegen. Fehlt eine explizite Angabe, wird die Voreinstellung aus der Konfigurationsdatei openssl.cnf entnommen. Ein typischer Wert ist 365.Unter Beachtung der Dateinamenskonventionen kann man das Zertifikat auch durch /usr/local/openssl/misc/CA.sh -sign erstellen. Als Gültigkeitsdauer sind hierbei 365 Tage eingestellt. Diese Einstellung kann durch Modifikation des Skripts CA.sh geändert werden.
Die Policy legt fest, für wen (d.h. für welche DN) Zertifikate ausgestellt werden können. Die Policy-Definitionen stehen in der Konfigurationsdatei openssl.cnf.
Schlüssel und Zertifikat für den Apache-Server installieren
-
privater Schlüssel (Direktive SSLCertificateKeyFile):
cp kirke_key /usr/local/apache/conf/ssl.key/server.key
-
Zertifikat (Direktive SSLCertificateFile):
cp kirke_cert /usr/local/apache/conf/ssl.crt/server.crt
-
Zertifikat der CA (Direktive SSLCertificateChainFile):
cp demoCA/cacert.pem /usr/local/apache/conf/ssl.crt/ca.crt
cp kirke_self_cert /usr/local/apache/conf/ssl.crt/server.crt
Zertifikat einer CA in den Browser laden
Die Liste der bekannten Zertifikate von CAs findet man bei Netscape 4.x unter Security --> Certificates --> Signers. Diese Liste kann erweitert werden, indem der Browser per HTTP ein Dokument mit dem MIME-Inhaltstypapplication/x-x509-ca-cert
lädt.Neben CA-Zertifikaten können auch Nutzer-, E-Mail- und Server-Zertifikate in den Browser geladen werden. Die entsprechenden Inhaltstypen lauten:
application/x-x509-server-cert application/x-x509-user-cert application/x-x509-email-cert
Das Laden von Zertifikaten kann z.B. über das Formular loadcert.html und das zugehörige CGI-Programm loadcert.pl erfolgen.
PKCS #12
Mit Hilfe dieses Formats kann der Netscape-Browser Zertifikate und private Schlüssel importieren und exportieren. Dies empfiehlt sich bei der (in der heutigen Praxis eher untypischen) Nutzung von Klienten-Zertifikaten für die Authentifizierung gegenüber einem WWW-Server. Diese Klienten-Zertifikate können mit OpenSSL generiert und konvertiert werden:-
Zertifikate und Schlüssel nach PKCS #12 exportieren:
openssl pkcs12 -export -in HINZ/hinz_cert.pem -inkey HINZ/hinz_req.pem -certfile demoCA/cacert.pem -name "hinz" -out hinz.p12
Wenn der Browser Netscape 4.x die Datei hinz.p12 importiert, fügt er das in der Datei demoCA/cacert.pem enthaltene Zertifikat der Demo-CA zur Liste der akzeptierten CAs hinzu (Security --> Certificates --> Signers). Das Zertifikat des Nutzers Hinz ist unter Security --> Certificates --> Yours zu finden. -
Anzeige von Informationen, die im Format PKCS #12 vorliegen:
openssl pkcs12 -info -in hinz.p12
Fortify
Damit kann die in den für den Export bestimmten Netscape-Browsern nutzbare Menge von Cipher Suites für SSL erweitert werden.-
bei Apache/mod_ssl standardmäßig verfügbare Cipher Suites:
ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
-
detaillierte Anzeige der bei OPENSSL verfügbaren Cipher Suites:
bei tcsh:
openssl ciphers -v 'ALL:\!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'
bei bash/sh:openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'
Zugriff auf einen Apache-Server mittels Netscape und SSL
-
ohne Klienten-Authentifizierung:
-
Falls die CA des Server-Zertifikats bekannt ist, wird der Server
vom Browser sofort akzeptiert.
- Anderenfalls muß man in einem Dialog entscheiden, ob und wie lange das Zertifikat der Servers akzeptiert wird. Das Zertifikat kann für die aktuelle Sitzung oder bis zum Ende seiner Gültigkeit akzeptiert werden.
-
Falls die CA des Server-Zertifikats bekannt ist, wird der Server
vom Browser sofort akzeptiert.
-
mit Klienten-Zertifikaten (Security --> Certificates -->
Yours)
Beispiel für die Datei .htaccess, die den Zugriff auf Dokumente nur gestattet, wenn der Klient ein Zertifikat für den fiktiven Nutzer hinz vorweist:
SSLVerifyClient require SSLVerifyDepth 5 SSLRequireSSL SSLRequire \ ( %{SSL_CLIENT_S_DN } eq "/C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=hinz/Email=hinz@informatik.tu-chemnitz.de" )
-
mit Klienten-Zertifikaten und FakeBasicAuth bei Apache/mod_ssl
Beispiel für .htaccess:
SSLVerifyClient require SSLVerifyDepth 5 SSLRequireSSL AuthName SSLFake AuthType Basic AuthUserFile /usr/local/apache/conf/httpd.passwd require valid-user
Mit welchen Zertifikaten zugegriffen werden darf, wird in der durch AuthUserFile spezifizierten Paßwort-Datei festgelegt. Als Nutzerkennzeichen ist dabei der Inhalt des Feldes Subject des Zertifikats anzugegeben. Sofern die UNIX-typische, auf dem DES basierende Paßwort-Verschlüsselung genutzt wird, ist als Paßwort immer die konstante Zeichenkette xxj31ZMTZzkVA einzutragen (das ist die Verschlüsselung des Wortes password).Beispiel für eine Paßwort-Datei mit zwei Einträgen:
/C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=hinz/Email=hinz@informatik.tu-chemnitz.de:xxj31ZMTZzkVA Rum:4YQK85NGp4Jj2
Der erste Eintrag enthält das Subject des Zertifikats von Nutzer hinz sowie die Verschlüsselung des konstanten Paßwortes password. Der zweite Eintrag besteht aus dem Nutzernamen Rum sowie dessen verschlüsseltem Paßwort (hier konkret topf). -
cgi-bin/printenv mit Option ExportCertData
-
Zugriff mit s_client oder SSL-Telnet und manuellem HTTP
Beispiele:
- mit bekannter CA:
openssl s_client -quiet -connect kirke:443 -CAfile demoCA/cacert.pem depth=1 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke_ca/Email=hot@informatik.tu-chemnitz.de verify return:1 depth=0 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke.informatik.tu-chemnitz.de/Email=hot@informatik.tu-chemnitz.de verify return:1 GET /
- mit unbekannter CA, wobei der Server nur sein eigenes Zertifikat sendet:
openssl s_client -quiet -connect kirke:443 depth=0 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke.informatik.tu-chemnitz.de/Email=hot@informatik.tu-chemnitz.de verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke.informatik.tu-chemnitz.de/Email=hot@informatik.tu-chemnitz.de verify error:num=27:certificate not trusted verify return:1 depth=0 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke.informatik.tu-chemnitz.de/Email=hot@informatik.tu-chemnitz.de verify error:num=21:unable to verify the first certificate verify return:1 GET /
- mit unbekannter CA, wobei der Server eine Zertifikatskette sendet, die
neben seinem eigenen Zertifikat auch noch das selbstzertifizierte
Zertifikat seiner CA enthält:
openssl s_client -quiet -connect kirke:443 depth=1 /C=DE/ST=Saxony/L=Chemnitz/O=Chemnitz University of Technology/OU=Department of Computer Science/CN=kirke_ca/Email=hot@informatik.tu-chemnitz.de verify error:num=19:self signed certificate in certificate chain verify return:0
- mit bekannter CA:
SSL-Telnet
Der Server ließ sich in den Tests nur im Debug-Modus sinnvoll betreiben. Im Normalmodus, wenn er vom inetd gestartet wird, wird die Verbindung sehr früh beendet. Die Ursache ist unklar.Der Telnet-Server entnimmt seinen privaten Schlüssel sowie sein Zertifikat standardmäßig der Datei /usr/local/openssl/certs/telnetd.pem. Hierfür ist z.B. die weiter unten bei Stunnel genutzte Datei kirke.stunnel verwendbar:
cp KIRKE/kirke.stunnel /usr/local/openssl/certs/telnetd.pem
Start des Servers:
-
telnetd -debug -z ssl
Es werden nur SSL-Verbindungen akzeptiert. -
telnetd -debug -z secure
Telnet-Klienten, die kein SSL verwenden, werden mit dem Hinweistelnetd: [SSL required - connection rejected].
abgewiesen. -
telnetd -debug -z secure -z key=KIRKE/kirke_key -z cert=KIRKE/kirke_cert
Schlüssel und Zertifikat des Servers werden explizit spezifiziert.
Nutzung des Klienten ohne Zertifikat (anonymes SSL bei Telnet, HTTP ...):
telnet -z ssl kirke telnet -z ssl kirke 443
Nutzung des Klienten mit Zertifikat:
telnet -z ssl -z cert=hinz_cert.pem -z key=hinz_req.pem kirke 443
s_client und s_server
Hierbei handelt es sich um einen SSL-Klienten sowie einen SSL-Server. Beide sind Bestandteil von openssl und eignen sich für Tests. Im folgenden werden einige Benutzungsbeispiele gezeigt.Klient:
openssl s_client -connect kirke:443 openssl s_client -cipher DES-CBC-SHA -connect kirke:443 openssl s_client -connect kirke:443 -key hinz_req.pem -cert hinz_cert.pem
HTTP-Anweisungen:GET /test/SSLrequire/1.html GET /sslcgi/printenv
Server:
-
einfacher Test-Server für interaktive Arbeit:
openssl s_server -key kirke_key -cert kirke_cert openssl s_server
Hier hört der Server am Default-Port 4433. Standardmäßig werden privater Schlüssel und Zertifikat aus der Datei server.pem gelesen. Hierfür ist die weiter unten bei Stunnel genutzte Datei kirke.stunnel verwendbar.openssl s_server -accept 8000 -key kirke_key -cert kirke_cert
Hier hört der Server auf Port 8000. Der Klient kann z.B. so darauf zugreifen:openssl s_client -connect kirke:8000
-
einfacher WWW-Server mit Status-Seite (unter URL
https://localhost:8000):
openssl s_server -accept 8000 -www -key kirke_key -cert kirke_cert
-
einfacher WWW-Server, der einen Datei-Zugriff gestattet,
z.B. unter dem URL https://localhost:8000/test_seite:
openssl s_server -accept 8000 -WWW -key kirke_key -cert kirke_cert
privaten Key durch Netscape-Browser erstellen und per WWW zertifizieren lassen
Die HTML-Seite ca.html aus dem Paket Stunnel initiiert über das TagDas CGI-Programm ca.pl realisiert die Zertifizierung durch
openssl ca -batch ...
und sendet das Ergebnis alsContent-type: application/x-x509-user-cert
zurück.
Stunnel
Dieses Werkzeug stellt universelle SSL-Tunnel bereit.- Stunnel Version 3.x:
Sofern stunnel als SSL-Server fungiert, benötigt das Programm eine Text-Datei, die sowohl den privaten Schlüssel als auch das Zertifikat enthält. Beide Informationen sind im PEM-Format bereitzustellen und werden durch folgende Trenner begrenzt:
-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
bzw.-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----
Erzeugung einer solchen Datei:cat kirke_key kirke_cert > kirke.stunnel
Anwendungsbeispiele für den SSL-Tunnel:-
Schutz eines eigenen Echo-Servers echo.c (dessen
Aufruf erfolgt wie bei inetd):
stunnel -d 9000 -p KIRKE/kirke.stunnel -f -l ./echo
-
Zugriff auf diesen Server mittels s_client:
openssl s_client -quiet -connect kirke:9000 -CAfile demoCA/cacert.pem openssl s_client -quiet -connect kirke:9000
-
verschlüsselten Verkehr durch Sniffer beobachten, z.B. mittels
ethereal:
- Capture Filter:
tcp port 9000
- Anzeige:
Tools --> Follow TCP Stream
- Capture Filter:
-
Echo-Server als Daten-Generator arbeiten lassen:
stunnel -d 9000 -p KIRKE/kirke.stunnel -f -l ./echo echo 1
-
Nutzung des Klienten-Modus von Stunnel:
stunnel -f -c -d 5000 -r 443
Stunnel hört hier auf Port 5000 und leitet jede Verbindungsanforderung über SSL zum Port 443 weiter.Beispiel-Klient:
telnet kirke 5000
Durch normales Telnet zum Port 5000 erreicht man den SSL-fähigen WWW-Server am Port 443 über SSL.Ein weiteres Nutzungsbeispiel ist der Schutz der IMAP-Verbindung des Mail-Agenten Pine, wie dies z.B. im Shell-Skript secure_imap gezeigt wird. Die Ermittlung eines freien TCP-Ports erfolgt hierbei über das Programm free_tcp_port.c.
-
Schutz eines eigenen Echo-Servers echo.c (dessen
Aufruf erfolgt wie bei inetd):
-
Stunnel Version 4.x:
Der Aufruf der Software hat sich deutlich geändert. Typischerweise sieht er so aus:
stunnel config_file
Über die als Argument benannte Konfigurationsdatei steuert man die Arbeitsweise des Tunnels.Hier ein kleines Beispiel für eine Konfigurationsdatei:
cert = /usr/local/stunnel/mycert chroot = /var/run/stunnel # PID is created inside chroot jail pid = /pids/stunnel.pid setuid = nobody setgid = wheel debug = 7 output = /var/run/stunnel/stunnel.log client = yes [https] accept = 80 connect = libero:443 TIMEOUTclose = 0 [https1] accept = 81 connect = opac:443 TIMEOUTclose = 0
Stunnel arbeitet hier im Klienten-Modus, d.h., der entfernte Server unterstützt SSL, der lokale Klient dagegen nicht.
Die Service-Definition [https] bewirkt, daß der Tunnel auf Port 80 hört und eingehende Verbindungswünsche an den Port 443 (https) von Rechner libero weiterleitet.
Die Service-Definition [https1] bewirkt, daß der Tunnel auf Port 81 hört und eingehende Verbindungswünsche an den Port 443 (https) von Rechner opac weiterleitet.
Unter Verwendung des Tunnels kann man mit einem beliebigen Klienten, der kein SSL beherrscht, auf ein per SSL zugängliches Angebot zugreifen, z.B. so:
telnet localhost 80 GET /cgi-bin/nph-mgwcgi?LANG=Deutsch&login='start'&VERSION=2
−InhaltsverzeichnisOpenSSL-Zertifikate
Anzeigen/Prüfen
- Zertifikat komplett anzeigen
openssl x509 -noout -text -in <zertifikatsname.crt>
- den Herausgeber des Zertifikats anzeigen
openssl x509 -noout -issuer -in <zertifikatsname.crt>
- Für wen wurde das Zertifikat ausgestellt?
openssl x509 -noout -subject -in <zertifikatsname.crt>
- Für welchen Zeitraum ist das Zertifikat gültig?
openssl x509 -noout -dates -in <zertifikatsname.crt>
- das obige kombiniert anzeigen
openssl x509 -noout -issuer -subject -dates -in <zertifikatsname.crt>
- den hash anzeigen
openssl x509 -noout -hash -in <zertifikatsname.crt>
- den MD5-Fingerprint anzeigen
openssl x509 -noout -fingerprint -in <zertifikatsname.crt>
- ein SSL-Zertifikat prüfen
openssl verify -CApath /etc/pki/tls/certs -verbose <zertifikatsname.crt>
- einen SSL-Port auf Zertifikate abfragen
openssl s_client -CApath /etc/pki/tls/certs -connect localhost:636 -showcerts
Passphrase entfernen/ändern
- Passphrase für ein Keyfile entfernen
openssl rsa -in <zertifikatsname.key> -out <neueskeyfile.key>
- Passphrase für ein Keyfile ändern
openssl rsa -des3 -in <zertifikatsname.key> -out <neueskeyfile.key>
CSR erzeugen/anzeigen
- einen CSR + Keyfile erzeugen (für die Beantragung eines echten Zertifikats). Das <zertifikatsname.csr> sendet man danach an die zertifizierende Stelle, z.B. Thawte etc.
# 2048 Bit RSA-Key erzeugen openssl genrsa -out <zertifikatsname.key> 2048 # den CSR dazu erzeugen openssl req -new -key <zertifikatsname.key> -out <zertifikatsname.csr> # den Key mit einer Passphrase versehen openssl rsa -des3 -in <zertifikatsname.key> -out <zertifikatsname.key.sec>
- einen CSR (Zertifikatsrequest) anzeigen
openssl req -noout -text -in <request.csr>
Zertifikate konvertieren
- PEM nach DER
openssl x509 -outform der -in certificate.pem -out certificate.der
- PEM nach P7B
openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer
- PEM nach PFX
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
- DER nach PEM
openssl x509 -inform der -in certificate.cer -out certificate.pem
- P7B nach PEM
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
- P7B nach PFX
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer
- PFX nach PEM
openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes
-
Generierung eines RSA-Schlüssels ohne Paßwortschutz (für Server-Betrieb
sinnvoll):