SSL Verschlüsselung von Webseiten prüfen

Autoren: Michael Gisbers and Christian Hesse

Nachdem wir das Thema OpenSSH mit dem Linux Tip im September abgeschlossen haben, wenden wir uns nun der SSL-Verschlüsselung zu. Den folgenden Dialog hat jeder schon in seinem Browser gesehen:

Diese Warnung erscheint immer, wenn der Administrator einer Website auf dem über SSL abgesicherten Server kein durch ein Trustcenter beglaubigtes Zertifikat hinterlegt hat oder dieses aus einem anderen Grund nicht gültig ist.

Über das 'Zertifikat' ('Certificate' oder kurz 'Cert') prüft der Webbrowser, ob der Schlüssel des Servers unverändert und der Servername korrekt ist.

Ein Zertifikat wird für eine Schlüsseldatei (Key) ausgestellt. Diese Schlüsseldatei ermöglich dem Server, Daten zu verschlüsseln oder zu entschlüsseln.

Informationen wie der Servername ('CommonName' oder kurz 'cn') sind im Zertifikat hinterlegt. Darüber hinaus sind weitere Informationen vom Gültigkeitszeitraum über den Verwendungszweck bis zu Aussteller ('Issuer') des Zertifikats enthalten.

 

 

Bei dem Aussteller kommen die Trustcenter ins Spiel. Dies sind Zertifizierungsinstanzen, die durch spezielle Sicherheitsrichtlinien sicherstellen, dass ihre hinterlegte Zertifikatsautorität ('Certificate Authority' oder kurz 'CA') vertrauenswürdig ist. Von dieser CA werden die ausgestellten Zertifikate signiert und damit bescheinigt, dass die Zertifikate gültig sind. Um diesen Weg nachvollziehen zu können, werden im Webbrowser und den Betriebssystemen die Zertifikate der CA hinterlegt.

Nach all dieser Theorie schauen wir uns einen Verbindungsaufbau per SSL zu einem Server an:

user@linux ~ $ curl -Iv https://google.com
* About to connect() to google.com port 443 (#0)
*   Trying 173.194.70.139...
* Connected to google.com (173.194.70.139) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-ECDSA-AES128-GCM-SHA256
* Server certificate:
* 	 subject: C=US; ST=California; L=Mountain View;
* 	 O=Google Inc; CN=*.google.com
* 	 start date: 2013-09-11 11:10:44 GMT
* 	 expire date: 2014-09-11 11:10:44 GMT
* 	 subjectAltName: google.com matched
* 	 issuer: C=US; O=Google Inc; CN=Google Internet
* 	 Authority G2
* 	 SSL certificate verify ok.
> HEAD / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: google.com
> Accept: */*
[...]

Der hier benutzte Befehl `curl` gibt durch die Parameter `-v` (verbose, ausführlich) und `-I` (nur Header-Daten) eine ausführliche Einsicht in den Verbindungsaufbau.

Zunächst wird die Verbindung zum Server hergestellt und dann das SSL Protokoll aktiviert. Server und `curl` tauschen dann das Zertifikat aus und einigen sich auf eine Verschlüsselung für die Verbindung.

In dem Block `Server certificate` ist dann die eigentliche Information des Zertifikats zu sehen. Die wichtigste Aussage hierbei ist `SSL certificate verify ok.` Das Zertifikat passt also zum Server und der Weg zu einer Zertifizierungsinstanz kann überprüft werden.

Schon eine einfache Modifizierung ändert die Aussage:

user@linux ~ $ curl -vI https://173.194.70.139
[...]
* Server certificate:
* 	 subject: C=US; ST=California; L=Mountain View;
* 	 O=Google Inc; CN=*.google.com
* 	 start date: 2013-09-11 10:50:21 GMT
* 	 expire date: 2014-09-11 10:50:21 GMT
* SSL: certificate subject name '*.google.com' does not
* match target host name '173.194.70.139'
* Closing connection 0
* SSLv3, TLS alert, Client hello (1):
curl: (51) SSL: certificate subject name '*.google.com' does
not match target host name '173.194.70.139

In diesem Beispiel wurde die Adresse, die vorher zum Verbindungsaufbau zum Server benutzt wurde, statt des Servernamens in der URL benutzt. Sofort gibt `curl` die Fehlermeldung aus und informiert über den Grund für die Ablehnung des Zertifikats. Um trotzdem den Verbindungsaufbau komplett durchführen zu können, müsste `curl` der Parameter `-k` (oder `--insecure`) mitgegeben werden. Hierdurch werden Zertifikatsprobleme ignoriert.

Ein weiterer Weg, sich Informationen über die Verbindung zu einem Server zu beschaffen, ist der Allrounder `openssl`. Dieser wird nicht nur zum Erzeugen von Schlüsseln, Zertifikatsanforderungen oder Zertifikaten eingesetzt, sondern auch für den Test von SSL-Servern:

user@linux ~ $ echo "QUIT" | openssl s_client -connect google.com:443 -CApath /etc/ssl/certs
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate
Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet
Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O =
Google Inc, CN = *.google.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google
Inc/CN=*.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google
Inc/CN=*.google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
---
No client certificate CA names sent
---
SSL handshake has read 4410 bytes and written 448 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID:
68CE9DF986DDA1A70673B153EB0CDF3330AD443A943BDE94217AC67C4AF4CB8B
    Session-ID-ctx: 
    Master-Key:
3A68C9BE21DAB36E8D1CFAD12462A2CC460C5E7B05C828B8B79E96FA5BFCBD8B7533AF33C1EC66B66B86E9C9DBF57AFA
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    [...]
    Start Time: 1380707062
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
DONE
----

Der Aufruf ist hier ein wenig umständlicher, liefert aber deutlich mehr Informationen. Zunächst wird dem Programm der Text `QUIT` in die Standardeingabe gegeben, um die Verbindung sauber zu beenden. Ohne dieses `QUIT` würde die Verbindung bestehen bleiben und das Programm müsste durch eine Unterbrechung (`Strg+C`) abgebrochen werden.

Der Parameter `-connect` gibt den Server und den Port für den Test an. Üblicherweise ist der Port für SSL `443`.

Da `openssl` keine eigene Datenbank für Zertifikate hat, greift es auf die im Betriebssystem hinterlegte Datenbank zurück. `-CApath` benötigt daher den Pfad dorthin.

Mit diesen beiden Tools (`curl` und `openssl`) besteht die Möglichkeit, die Zertifikate der SSL verschlüsselten Serververbindungen auch abseits von den Meldungen im Webbrowser testen zu können.

Die nächsten Artikel dieser Reihe behandeln weitere Möglichkeiten des Befehls `openssl` zur Erzeugung von Schlüsseln, Zertifikatsanfragen und Zertifizierung. Auch den möglichen Zertifikatsarten gehen wir genauer auf den Grund.