• Helmut Weber
  • 06.07.2011

Eigene SSL-Zertifikate mit CA erstellen


Während der Umsetzung eines Projektes wurde an uns die Anforderung heran getragen, die Applikation die wir gerade für den Kunden erstellen, mit einem SAP-System des Kunden zu verbinden. Dadurch soll es möglich sein, Bestellungen in Echtzeit an das SAP-System zu übermitteln, und die Verfügbarkeit der gewünschten Produkte einzusehen. Neben den hohen Hürden für den Kommunikations-Aufbau beider Systeme (VPN-Verbindung, Firewall, etc.), war eine verschlüsselte Verbindung die Voraussetzung für den Aufbau einer Kommunikation.

Eine verschlüsselte Verbindung wird mittels SSL (Secure Sockets Layer) aufgebaut. Hierfür sind wiederum X.509-Zertifikate notwendig. Ein solches Zertifikat kann entweder selbst, oder von einer Zertifizierungsstelle (englisch Certificate Authority, oder kurz CA) signiert werden. In den meisten Clients (z.B. Web-Browser) sind mehrere Zertifizierungsstellen bereits hinterlegt, wodurch die darüber signierten Zertifikate vom Browser automatisch angenommen werden. Bei selbst signierten Zertifikaten müssen diese immer vor der ersten Benutzung in den Client eingebunden werden.

Muss man nun mehrere eigene Zertifikate in Clients einbinden kann es von Vorteil sein, eine eigene Zertifizierungsstelle (CA) aufzubauen, über diese die selbst erstellten Zertifikate signiert werden können. Dadurch müssen in den Clients nur die Zertifizierungsstelle bekannt gemacht werden, über diese dann die Zertifikate auf Gültigkeit geprüft werden können.

In dieser Dokumentation möchten wir nun das Erstellen einer CA sowie eines Serverzertifikates beschrieben. Dieses Zertifikat werden wir dann mit der CA signieren, und auf Funktion testen. Fangen wir also Schritt für Schritt an.

Voraussetzungen

Auf Linux-Systemen kommt für die Verwaltung der Zertifikate sowie das Verschlüsseln der Verbindungen überwiegend OpenSSL zum Einsatz. Daher ist OpenSSL auf den meisten Linux-Servern bereits installiert. Sollte dies nicht der Fall sein kann dies einfach über die Paketverwaltung nachgeholt werden. Hier am Beispiel eines Debian-Derivates:

aptitude install openssl

OpenSSL beinhaltet nicht nur die Funktionen um auf dem System die Verschlüsselungstechniken bereit zu stellen, sondern bringt auch Terminalbefehle mit, mit denen sich Schlüssel und Zertifikate erstellen lassen. Diese nutzen wir in den folgenden Abschnitten.

Erstellen einer Zertifizierungsstelle (CA)

Beginnen wir also eine Zertifizierungsstelle (CA) aufzubauen. Als Erstes legen wir ein Verzeichnis an, in dem wir alle nachfolgenden Befehle ausführen und die Zertifikats- sowie Schlüssel-Dateien ablegen:

mkdir /home/username/crt
cd /home/username/crt

Eine CA besteht selbst aus einem Zertifikat, welche sich selbst signiert. Solch ein Zertifikat nennt man auch Root-Zertifikat. Mit folgendem Befehl wird ein solches Zertifikat mit der entsprechenden Schlüssel-Datei erzeugt:

openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout ca-key.pem -out ca-cert.pem

Für die Gültigkeit der CA wurde bewusst ein langer Zeitraum gewählt (hier 10 Jahre), weil jedes Zertifikat welches mit dieser CA signiert wurde, nach dem Ablauf der Gültigkeit der CA ebenfalls ungültig wird.

Der Dateiname der Schlüssel-Datei kann mit dem Paramater -keyout angegeben werden. Da mit diesem Schlüssel beliebige Serverzertifikate singniert werden können, muss dieser mit einer Passphrase verschlüsselt werden. Diese Passphrase bitte gut merken, da man diese für das Erzeugen eines Zertifikates benötigt.

Im darauf folgenden Dialog wird man gebeten weitere Angaben zu machen, welche den Aussteller der CA näher identifizieren.

Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Baden-Wuerttemberg
Locality Name (eg, city) []:Ellhofen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bitbetrieb
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:CA
Email Address []:info@bitbetrieb.de

Bei Common Name sollte man bei der CA nicht den Hostname des Rechners eintragen, sondern eine andere Bezeichnung (z.B. CA). Möchte man ein Feld leer lassen, so muss an dieser Stelle ein Punkt eingegeben werden. Ansonsten wird der Standardwert übernommen, der in den eckigen Klammern steht. Die einzelnen Felder haben folgende Bedeutung:

Country Name
Land im 2-stelligen ISO-Code (z.B. DE)
State or Province Name
Name des States, bzw. Bundeslandes
Locality Name
Name der Stadt
Organization Name
Name der Organisation bzw. Firma
Organizational Unit Name
Name der Abteilung
Common Name
Bezeichnung der CA
Email Address
Die E-Mail-Adresse des Erstellers

Danach sollten die Schlüssel-Datei (ca-key.pem) und die Zertifikats-Datei (ca-cert.pem) im Verzeichnis liegen. Die Rechte der Schlüssel-Datei sollten nur auf den root-Benutzer beschränkt werden, damit kein anderer Benutzer diese einsehen oder verändern kann:

chmod 600 ca-key.pem

Erzeugen eines Certificate Signing Request (CSR)

Nachdem wir nun eine CA haben, mit deren Hilfe wir Zertifikate signieren können, machen wir uns daran ein Serverzertifikat zu erstellen. In unserem Fall hat der Kommunikationspartner auf dem SAP-System das Serverzertifikat erstellt. In dieser Dokumentation möchten wir trotzdem darstellen, wie dies geschieht.

Der Befehl hierfür ähnelt dem für die Erstellung eines Zertifikates für die CA:

openssl req -new -nodes -newkey rsa:1024 -keyout server-key.pem -out server-csr.pem -days 365

Hiermit wird wieder eine Schlüssel-Datei sowie ein Certificate Signing Request erzeugt. Mit dem Parameter -nodes erreicht man, dass die Schlüssel-Datei ohne Passphrase erstellt wird, da das erzeugte Zertifikat sonst nicht ohne Eingabe dieser Passphrase verwendet werden kann. Hierbei werden erneut Daten abgefragt, welche den Zertifikats-Inhaber näher identifizieren. Zum Unterschied bei den Angaben der CA, muss unter Common Name der vollständige Domainname stehen, unter diesem der Server zu erreichen ist. Die Gültigkeitsdauer eines Serverzertifikates ist meist wesentlich kürzer wie bei einem CA (1-2 Jahre).

Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Baden-Wuerttemberg
Locality Name (eg, city) []:Ellhofen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bitbetrieb
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:www.example.org
Email Address []:info@bitbetrieb.de

Nun liegen in unserem Verzeichnis zwei weitere Dateien. Nämlich die Schlüssel-Datei server-key.pem sowie der Certificate Signing Request server-csr.pem.

Das Certificate Signing Request kann mit folgendem OpenSSL-Befehl angezeigt werden:

openssl req -noout -text -in server-csr.pem

Signieren des Certificate Signing Request

Bevor wir den Certificate Signing Request mit der CA signieren können, müssen bestimmte Verzeichnisse und Dateien angelegt werden, damit OpenSSL die zu signierenden Zertifikate verwalten kann. Bei OpenSSL heißt dieses Verzeichnis standardmäßig demoCA, und muss weitere Unterverzeichnisse und Dateien enthalten, die wir zuerst anlegen müssen. In der Konfigurations-Datei von OpenSSL /usr/lib/ssl/openssl.cnf können die Verzeichnisse auf Wunsch angepasst werden.

mkdir -p demoCA
mkdir -p demoCA/certs
mkdir -p demoCA/crl
mkdir -p demoCA/newcerts
mkdir -p demoCA/private
touch demoCA/index.txt
echo 01 > demoCA/serial

In unserem Fall waren haben nicht alle Angaben der CA mit den Angaben des Certificate Signing Request übereingestimmt (z.B. State or Province Name und Organization Name). OpenSSL kann jedoch so eingestellt werden, dass diese Felder ignoriert werden. Dazu muss die Datei /usr/lib/ssl/openssl.cnf wie folgt angepasst werden:

# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

Nun können wir den Certificate Signing Request mit unserer CA signieren. Hierfür nutzen wir wieder einen Befehl von OpenSSL:

openssl ca -in server-csr.pem -cert ca-cert.pem -keyfile ca-key.pem -days 365 -out server-cert.pem

Hier muss wieder die Passphrase eingegeben werden, die zu Beginn für die CA vergeben wurde. Danach wird eine Übersicht des zu signierenden Zertifikats angezeigt, welches man noch bestätigen muss.

Wenn alles geklappt hat, haben wir nun in unserem Verzeichnis das Serverzertifikat mit dem Dateinamen server-cert.pem vorliegen, welches bereit für den Einbau in einen Serverdienst ist.

Außerdem wird in der vorher angelegten Verzeichnisstruktur durch das Signieren die Seriennummer der Datei demoCA/serial hochgezählt, und jedes neue Zertifikat in die Datei demoCA/index.txt eingetragen. Jedes signierte Zertifikat wird zusätzlich im Verzeichnis demoCA/newcerts abgelegt. Der Dateiname setzt sich aus der Seriennummer des Zertifikates sowie der Dateierweiterung .pem zusammen.

Testen des Zertifikates

Um Sicher zu gehen, dass alles ordnungsgemäß verlaufen ist, sollten wir das Serverzertifikat vor der Weitergabe testen. Mit OpenSSL kann man nicht nur Zertifikate erstellen sowie signieren, sondern auch das gerade signierte Zertifikat einsehen:

openssl x509 -in server-cert.pem -noout -text -purpose

Auch zum Überprüfen, ob das Zertifikat in Verbindung mit der CA gültig ist, lässt sich OpenSSL einsetzen:

openssl verify -CAfile ca-cert.pem -verbose server-cert.pem

Wenn nach diesem Befehl OpenSSL mit OK antwortet sind alle Vorbereitungen getroffen, um das Zertifikat produktiv einzusetzen. Wir haben in unserem Fall das signierte Zertifikat an unseren Kommunikationspartner weiter gegeben, der dieses in den SAP-Server integriert hat.

Testen mit Lynx

Bevor nun das Zertifikat in der unserer Applikation eingesetzt wird, ist es Sinnvoll ganz rudimentär den Aufbau einer verschlüsselten Verbindung mit dem Textbrowser Lynx zu testen. Dadurch kann man Fehler in der Applikation ausschließen, und sich rein auf die verschlüsselte Verbindung konzentrieren.

In der Konfigurations-Datei von Lynx (/etc/lynx-cur/lynx.cfg) muss die Verwendung der gerade erstellen CA-Datei angegeben werden:

#SSL_CERT_FILE:/etc/ssl/certs/ca-certificates.crt
SSL_CERT_FILE:/home/hweber/ca/ca-cert-spiap.pem
#SSL_CERT_FILE:NULL

Nun bauen wir auf der Kommandozeile mittels Lynx eine Verbindung mit unserem Kommunikationspartner auf:

lynx https://www.example.org/index.html

Wenn der Verbindungsaufbau erfolgreich ist, und kein Zertifikatsfehler gemeldet wird, steht dem Einbinden des Zertifikats in die Applikation nichts mehr im Wege. In unserem Fall wurde die verschlüsselte Verbindung mit der Programmiersprache Perl und dem Modul IO::Socket::SSL realisiert.

Weiterführende Links

Für das Erzeugen der Zertifikate sowie für die Erstellung dieser Dokumentation, haben mir folgenden Seiten maßgeblich geholfen:

http://wiki.a-enterprise.ch/index.php/Server_SSL-Zertifikate_Erstellen
http://dozent.maruweb.de/material/ca.shtml
http://blog.datenritter.de/archives/200-eigene-X.509-Zertifikats-Hierarchie-mit-OpenSSL-CA,-Client-Server.html
http://www.howtoforge.de/howto/howto-selbstsigniertes-ssl-zertifikat-erstellen/
http://www.online-tutorials.net/security/openssl-tutorial/tutorials-t-69-207.html
http://www.magenbrot.net/wiki/linux/kryptographie/openssl-zertifikate
http://www.dfn-cert.de/informationen/themen/verschluesselung_und_pki/openssl-kurzreferenz.html