Für Anwendungen wie etwa OpenVPN, oder auch generell für Intranetanwendungen die SSL benutzen sollen, wird eine eigene CA (Certificate Authority) benötigt, die digitale Zertifikate ausstellt. Mit Openssl läßt sich solch eine CA betreiben.
Wozu eigentlich eine eigene interne CA, wenn Zertifikate auuch selbst signiert werden können? Ein selbstsigniertes Zertifikat wird von SSL-Clients als ungültig abgelehnt solange sie dieses Zertifikat nicht kennen. Wird das selbstsignierte Zertifikat im Client gespeichert, wird er es fortan akzeptieren. Betreibt man jedoch viele Serverdienste mit SSL und hat viele Clients, bedeutet es einen großen Aufwand jedem Client, jedes selbstsignierte Zertifikat bekannt zu geben. Mit einer CA werden die Zertifikate von der CA signiert. Kennt ein Client nun das Zertifikat der CA, wird er jedes Zertifikat welches von dieser CA signiert wurde als gültig akzeptieren. Die Clients müssen also nur noch ein CA Zertifikat zusätzlich lernen (welches außerdem eine längere Gültigkeitsdauer hat), als viele einzelne selbstsignierte Serverzertifikate.
Openssl ist nicht nur eine Bibliothek die Programmfunktionen für SSL bereit stellt, sondern enthält ebenso ein Kommandozeilenprogramm mit dem sich Schlüssel und Zertifikate erstellen lassen. Dieses Kommandozeilenprogramm hat sehr viele Optionen und es läßt sich gleichermassen nutzen um Serverzertifikate zu generieren, als auch um Passworthashes zu generieren und ebenso als vollständige CA.
Alle Openssl Kommandos werden mit openssl
aufgerufen. Openssl hat Unterkommandos für seine vielen Funktionen. Das gewünschte Unterkommando wird beim Aufruf von openssl
als erstes Argument übergeben, danach folgen die Optionen des jeweiligen Unterkommandos. Die Namen aller Unterkommandos lassen sich mit openssl list-standard-commands
auflisten. Die folgende Tabelle zeigt eine Übersicht über einige der wichtigsten Unterkommandos.
Kommando | Bedeutung |
---|---|
ca | Verwaltung einer CA. |
dsaparam | Erzeugung einer DSA Parameter Datei. |
genrsa | Erstellung eines RSA Schlüssels. |
gendsa | Erstellung eines DSA Schlüssels. |
req | Verwaltung von X.509 Certificate Signing Requests. |
verify | Verifizierung von X.509 Zertifikaten. |
x509 | X.509 Zertifikatsmanagement. |
Die drei wichtigsten Unterkommandos zum Betrieb einer CA und zum erzeugen von Zertifikaten sind ca
, welches alle Operationen für den Betrieb der CA zur Verfügung stellt, wie etwa das signieren von Certificate Signing Requests, req
zum erzeugen eines Certificate Signing Requests, aber auch zum erzeugen selbstsignierter Zertifikate und x509
welches ein generelles Kommando zum Umgang mit Zertifikaten darstellt, welches Zertifikate konvertieren und anzeigen kann, aber auch in der Lage ist einfache CA Operationen wie etwa das Signieren selbst durchzuführen. Wie man am Kommando x509
sieht, überschneiden sich die Funktionen einiger Openssl Kommandos.
Openssl wird in fertigen Distributionspaketen häufig zusammen mit dem Script CA.pl ausgeliefert, welches ein Perlscript ist um eine CA zu verwalten. Das Script kapselt die eigentlichen openssl
Kommandos und dient als Vereinfachung. Um Openssl richtig kennenzulernen ist es jedoch hilfreich die eigentlichen Kommandos kennen zu lernen, so daß hier nicht weiter auf dieses Script eingegangen wird. Möchte man ohnehin eine CA dauerhaft mit mehr Komfort betreiben, exitieren als Frontend zu Openssl mehrere grafische Programme, wie etwa TinyCA
, ein Perlscript welches GTK+2 für die grafische Oberfläche nutzt und xca
eine QT4 basierende Anwendung.
Da eine CA in einer PKI (Public Key Infrastructure) die Instanz ist, der alle anderen Rechner vertrauen, ist es wichtig eine CA bestmöglichst zu schützen. Keinesfalls sollte man eine CA direkt auf dem Rechner betreiben, der auch die Netzwerkdienste anbietet, für die die Zertifikate ausgestellt werden. In diesem Fall würde eine Kompromitierung dieses Servers auch automatisch eine Kompromitierung der gesamten CA bedeuten. Im Idealfall wird eine CA auf einem vom Netzwerk getrennten Einzelrechner betrieben, der in einem absperrbaren Zugangskontrollierten Raum steht. Ist eine CA einmal kompromitiert, kann der CA nicht mehr vertraut werden und alle ausgestellten Zertifikate sind wertlos.
Um nun eine CA anzulegen, benötigt die CA als erstes selbst ein Zertifikat. Da eine CA die Instanz ist die andere Zertifikate signiert, kann die CA ihr eigenes Zertifikat nur selbst signieren. Solch ein Zertifikat bezeichnet man als Root-Zertifikat. Zertifikate haben eine begrenzte Gültigkeitsdauer. Das Zertifikat einer CA muß in jedem Fall länger gültig sein, als die Zertifikate, die von ihr unterschrieben werden. Für ein CA Zertifikat wird daher eine relativ lange Gültigkeitsdauer gewählt, wie zum Beispiel 10 Jahre. Die Zertifikate die von der CA signiert werden, gelten meist nur für 1 - 2 Jahre.
Ein selbstsigniertes Root-Zertifikat für die CA wird mit openssl req
angelegt. Vor dieser Aktion sollte jedoch die Openssl-Konfigurationsdatei angepaßt werden. Openssl hat eine Konfigurationsdatei, die im Aufbau einer Windows INI Datei ähnelt. Meist ist sie unter /etc/ssl/openssl.cnf
zu finden. Diese Datei hat Bereiche, die jeweils durch einen Namen in eckigen Klammern abgegrenzt werden. Für die Unterkommandos req
und ca
kann es hier jeweils einen eigenen Bereich geben. Für den Betrieb einer CA muß außerdem auch noch ein Bereich [policy]
benutzt werden, der festlegt welche Attribute in einem Zertifikat angegeben werden müssen und welche nicht. Da zunächst nur req
eingesetzt wird, um das Root-Zertifikat der CA zu erstellen, wird in eine neue leere Konfigurationsdatei zunächst ein Bereich [req]
definiert. Die von Openssl mitgelieferte Konfigurationsdatei sollte nicht gelöscht, sondern umbenannt werden um diese für Referenzzwecke aufzuheben. Die neue neue Konfigurationsdatei könnte so aussehen:
[req]
default_bits = 1024
distinguished_name = req_distinguished_name
Mit default_bits
wird die Verschlüsselungsstärke eingestellt. Ohne diese Angabe verwendet Openssl einen 512 Bit RSA Schlüssel. Da 512 Bit für eine asymmetrische Verschlüsselung (welche größere Schlüsselstärken benötigt als symmetrische Verschlüsselung) nicht mehr besonders sicher ist, wird hier eine Verschlüsselungsstärke von 1024 Bit gesetzt. Sofern nicht anders angegeben wird RSA Verschlüsselung verwendet. Diese Angabe läßt sich auf der Kommandozeile mit der Option -newkey
überschreiben. Soll zum Beispiel ein 768 Bit RSA Schlüssel verwendet werden müßte -newkey rsa:768
angegeben werden. Möchte man stattdessen DSA Verschlüsselung, muß zuvor eine DSA Parameter Datei erstellt werden. Die Verschlüsselungsstärke wird dabei beim generieren der DSA Parameterdatei angegeben. Folgendes Kommando erstellt eine DSA Parameter Datei mit einer Stärke von 1024 Bit:
openssl dsaparam -out dsaparam 1024
Der Dateiname der Datei ist in diesem Beispiel einfach dsaparam
. Um anschließend die Datei beim erzeugen eines Schlüssels zu verwenden muß der Wert für die Option -newkey
so aussehen: -newkey dsa:dsaparam
.
Mit distinguished_name
wird der Name eines zusätzlichen Bereiches in der Konfigurationsdatei angegeben, in welchem die Fragen die beim erzeugen eines Zertifikats gestellt werden, konfiguriert werden. Diese Angabe ist notwendig um die zusätzlichen Attribute die ein SSL-Zertifikat benötigt angeben zu können. Diese zusätzlichen Attribute sind standardisiert. Folgende Attribute existieren:
Diese Namen existieren als Felder in jedem Zertifikat, was jedoch nicht heißt, das diese Felder auch alle Pflichtfelder sein müssen. Es können durchaus einzelne Felder (wie etwa organizationalUnitName
) leer bleiben. Darüber hinaus existieren noch ein paar weitere Felder die zusätzlich eingefügt werden können, wie vor allem emailAdress
, welches die Emailadresse des Inhabers enthält. In der Konfigurationsdatei müssen für diese Attribute Fragen angegeben werden, welche bei einem openssl req
Kommando gestellt werden. Die Antworten werden in die entsprechenden Felder des Zertifikats eingetragen. Der Bereich [req_distinguished_name]
könnte zum Beispiel so aussehen:
[req_distinguished_name]
countryName = Name des Landes als 2-Buchstabencode?
countryName_default = DE
countryName_min = 2
countryName_max = 2
stateOrProvinceName = Bundesland?
localityName = Stadt?
organizationName = Organisationsname (zum Beispiel Firmenname)?
organizationalUnitName = Abteilung?
commonName = Common Name (meist der Hostname)?
emailAddress = Email Adresse?
Zusätzlich zu den Fragen läßt sich für jedes Attribut auch ein Standardwert angeben, der benutzt wird, wenn eine Frage nicht beantwortet wurde. Dieser Standardwert wird mit attributName_default
angegeben. In diesem Beispiel wird dies für das Land mit countryName_default = DE
benutzt. Ebenso kann auch eine maximale Länge und eine minimale Länge für ein Attribut mit attributName_min
und attributName_max
angegeben werden.
Wurde die Konfigurationsdatei angelegt, kann nun ein selbstsigniertes Zertifikat für die CA erstellt werden:
openssl req -x509 -new -days 3650 -keyout privkey.pem -out pubkey.pem
Dieses Kommando verlangt zunächst eine Passphrase mit welcher der neue private Schlüssel verschlüsselt wird und fragt dann die vorher konfigurierten Fragen um die benötigten Attribute in das Zertifikat aufzunehmen. Dabei sollte allerdings für commonName
nicht der Hostname des CA Rechners angegeben werden, sondern eher etwas wie "CA". Anschließend werden die beiden Dateien pubkey.pem
und privkey.pem
erstellt, wobei privkey.pem
der neue private Schlüssel ist und pubkey.pem
das neue selbstsignierte Zertifikat ist. Die Option -x509
sorgt dafür das ein selbstsigniertes Zertifikat, statt eines Certificate Signing Requests erzeugt wird. Mit der Option -new
wird verlangt das ein neues Schlüsselpaar angelegt wird und die Option -days
gibt die Gültigkeitsdauer des Zertifikats in Tagen an. Hätte man ein unverschlüsseltes Zertifikat ohne Passphrase erstellen wollen, müßte die Option -nodes
angegeben werden. Dies sollte jedoch für ein CA Root-Zertifikat keinesfalls gemacht werden sollte, da die Passphrase das Zertifikat zusätzlich vor Missbrauch schützt. Die folgende Tabelle führt einige der wichtigsten Optionen von openssl req
auf:
Option | Bedeutung |
---|---|
-x509 | Erzeugt ein selbstsigniertes Zertifikat statt eines Certificate Signing Requests |
-new | Erzeugt einen neuen Certificate Signing Request (oder ein neues Zertifikat falls mit -x509 verwendet). |
-nodes | Erzeugt einen privaten Schlüssel der nicht zusätzlich mit einer Passphrase verschlüsselt ist. |
-days | Gibt die Gültigkeitsdauer des Zertifikats in Tagen an. |
-keyout | Datei in die der neue private Schlüssel geschrieben werden soll. |
-out | Datei in die der Certificate Signing Request oder das neue Zertifikat geschrieben wird. |
-newkey | Verschlüsselungsalgorithmus der verwendet werden soll. Zum Beispiel rsa:1024 für einen 1024 Bit RSA Schlüssel, oder dsa:dsaparam für einen DSA Schlüssel der die vorher erzeugte DSA-Parameter Datei dsaparam benutzt. |
-config | Normalerweise wird die Standardkonfigurationsdatei (meist /etc/ssl/openssl.cnf) benutzt. Hiermit wird eine alternative Datei als Konfigurationsdatei angegeben. |
-in | Datei aus der ein Certificate Signing Request gelesen wird. Darf nicht mit -new kombiniert werden. |
-key | Datei aus der ein privater Schlüssel gelesen wird. |
Möchte man sein frisch erstelltes CA Zertifikat mit allen enthaltenen Informationen betrachten, kann folgender Befehl verwendet werden:
openssl x509 -text -in pubkey.pem
Die Option -text
des x509
Kommandos dient dazu alle in einem Zertifikat enthaltenen Informationen als Klartext auszugeben. Mit der Option -in
wird das entsprechende Zertifikat angegeben.
Um eine CA zu betreiben muß die Konfigurationsdatei noch etwas erweitert werden. In der Konfigurationsdatei können dabei mehrere Bereiche mit jeweils unterschiedlichen Konfigurationen für eine CA erstellt werden, so das es unterschiedliche Profile innerhalb einer CA geben kann zum Beispiel für unterschiedliche Arten von Zertifikaten (Serverzertifikate, Clientzertifikate, etc.). Ein Bereich gilt dabei als Default CA und wird im [ca]
Bereich der Konfigurationsdatei angegeben. Der [ca]
-Bereich könnte daher so aussehen:
[ca]
default_ca = Myca
In diesem Beispiel muß es einen Bereich Namens [Myca]
geben, in der die Konfiguration für die Default CA steht:
[Myca]
dir = ./myca
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/cacert.pem
serial = $dir/serial
private_key = $dir/private/cakey.pem
default_md = sha1
default_days = 365
policy = mypolicy
Diese Konfiguration legt das Unterverzeichnis myca
als Ort für die CA-Dateien fest. Mit database
wird eine Textdatei definiert, in der alle neuen Zertifikate eingetragen werden. Mit new_certs_dir
wird ein Verzeichnis festgelegt in welches neu signierte Zertifikate kopiert werden. certificate
verweist auf das CA-Zertifikat und private_key
auf den privaten Schlüssel der CA. Mit serial
wird eine Textdatei angegeben die die nächste Seriennummer für die signierten Zertifikate enthält. default_md
bestimmt den verwendeten Hashalgorithmus (MD5 oder SHA1). Mit default_days
wird die Gültigkeitsdauer des neuen Zertifikates angegeben. Mit policy
wird ein zusätzlicher Bereich angegeben der die Policy für durch die CA zu signierende Zertifikate enthält. Dieser Bereich könnte zum Beispiel so aussehen:
[mypolicy]
countryName = supplied
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
Für einen Policy-Bereich muß zu jedem Attribut angegeben werden ob dieses mit dem entsprechenden Attribut des CA Zertifikates übereinstimmen muß (match), oder ob das Attribut zwar nicht übereinstimmen muß, aber vorhanden sein muß (supplied), oder ob das Attribut optional ist (optional). In diesem Beispiel müssen keine Attribute übereinstimmen, countryName
und commonName
müssen vorhanden sein, während alle anderen Angaben optional sind.
Anschließend muß noch die in der Konfigurationsdatei angegebene Verzeichnishierarchie angelegt werden. Mit den hier gezeigten Beispielen muß dazu das Unterverzeichnis myca
angelegt werden, welches die beiden Unterverzeichnisse private
und newcerts
enthalten muß. Außerdem muß die Datei index.txt
als neue leere Datei in diesem Verzeichnis angelegt werden. Ebenso muß auch die Datei für die Seriennummer angelegt werden. In diese Datei wird ein Startwert für die Serienummer geschrieben, zum Beispiel 01:
mkdir -p myca/private
mkdir myca/newcerts
touch myca/index.txt
echo "01" > myca/serial
Danach muß noch das vorher erzeugte Zertifikat (pubkey.pem
) nach myca/cacert.pem
und der private Schlüssel (privkey.pem
) nach myca/private/cakey.pem
kopiert werden. Um den privaten Schlüssel möglichst gut zu schützen werden auch noch die Rechte auf das Verzeichnis private
angepaßt:
mv pubkey.pem myca/cacert.pem
mv privkey.pem myca/private/cakey.pem
chmod 700 myca/private
Anschließend ist die CA bereit um Zertifikate zu signieren. Um nun etwas zu signieren wird ein Certificate Signing Request für ein Testzertifikat erstellt:
openssl req -new -nodes -days 730 -keyout testkey.pem -out testreq.req
Dies erzeugt die beiden Dateien testkey.pem
als neuen privaten Schlüssel und testreq.req
als Certificate Signing Request. Durch die Angabe der Option -nodes
wird der private Schlüssel nicht mit einer Passphrase verschlüsselt. Für Serverzertifikate ist dies meist erwünscht, da sonst bei jedem Start des Serverdienstes die Passphrase mit angegeben werden müßte. Durch -days 730
soll das Zertifikat eine Gültigkeitsdauer von 2 Jahren haben. Dieser Wert kann aber beim signieren durch die CA einfach überschrieben werden.
Um den Certificate Signing Request nun durch die CA zu signieren, ist folgender Befehl aus dem Verzeichnis oberhalb von myca
notwendig:
openssl ca -in testreq.req -out testcert.pem
Dabei wird nach der Passphrase des privaten CA Schlüssels gefragt. Anschließend werden die Attribute welche im Certificate Signing Request enthalten sind angezeigt und man wird gefragt ob dieses Zertifikat wirklich signiert werden soll. Beantwortet man die Frage mit y für yes, wird das Zertifikat in der neuen Datei testcert.pem
erstellt. Der Certificate Signing Request in testreq.req
kann anschließend gelöscht werden. Auf dem Server der das SSL Zertifikat nutzen soll, muß das neue Zertifikat zusammen mit dem privaten Schlüssel, der vorher erzeugt wurde, hinterlegt werden.
Beim signieren von Zertifikaten wird automatisch die Seriennummer in der Datei myca/serial
hochgezählt und jedes neue Zertifikat wird in die Datei myca/index.txt
eingetragen. Außerdem wird eine Kopie des Zertifikates in das Verzeichnis myca/newcerts
abgelegt. Die Kopie trägt den Dateinamen der Seriennummer plus der Erweiterung .pem
.
Die folgende Tabelle listet wichtige Kommandozeilenoptionen des openssl ca
Befehls auf:
Option | Bedeutung |
---|---|
-config | Wählt eine alternative Konfigurationsdatei aus. |
-in | Gibt die Datei mit dem Certificate Signing Request an, die signiert werden soll. |
-out | Datei in der das neue signierte Zertifikat gespeichert wird. |
-cert | Gibt die Datei mit dem CA Zertifikat an. |
-keyfile | Gibt den privaten Schlüssel der CA an. |
-days | Gibt die Gültigkeitsdauer des Zertifikats in Tagen an. |
-md | Gibt den verwendeten Hashalgorithmus an. Mögliche Werte md5 oder sha1. |
-name | Gibt den Namen des Bereichs in der Konfigurationsdatei an, der als Konfiguration verwendet werden soll. Möchte man einen anderen Bereich als den der default_ca benutzen muß diese Option verwendet werden. |
-policy | Gibt den Policy-Bereich in der Konfigurationsdatei an, der verwendet werden soll. |