OpenSSL Mini-CA (PKI)
Marvin Gülker · 02.11.2015
Eine tutorialartige Anleitung zur Benutzung von „openssl ca“ und Beschreibung, wie man seine eigene CA bzw. PKI mit OpenSSL betreibt.
Kategorien: Software
Achtung:
Eine selbstgebaute PKI ist zwar sehr interessant, genügt aber faktisch
niemals den hohen Sicherheitsanforderungen, die im Geschäftsfeld der
CAs gestellt werden. Zur mehr als Testzwecken oder nur kleinen
Betätigungsfeldern (etwa für die eigene Familie) ist sie aber durchaus
geeignet.
Grundlagen
Das Kürzel „PKI“ steht für „Public Key Infrastructure“ und bezeichnet den gesamten involvierten Stapel an öffentlichen (und privaten) Schlüsseln. Das sind im Minimalfall:
- CA-Zertfikat
- Server-Zertifikat (signiert durch CA-Zertifikat)
- Optional: Klient-Zertifikat (signiert durch CA-Zertifikat)
Eine solche PKI anzulegen ist eigentlich gar nicht einmal so schwierig, wenn es den von Seiten des OpenSSL-Projekts sauber dokumentiert wäre. Da man dort aber lieber Referenzdokumentation anstatt einführendes Material verfasst, steht man als Neuling (oder aus der Übung Gekommener) zunächst ziemlich auf dem Schlauch.
Das SSL/TLS-System funktioniert durch eine hierarchische Signierung. An der Spitze steht eine Zertifizierungsstelle (engl. Certificate Authority, CA), der man zwangsweise vertrauen muss, wogegen es nicht unerhebliche Bedenken gibt. Alternative Lösungen werden diskutiert, aber die einzig praktikable Alternative als völlig dezentrales System bietet zurzeit nur GnuPG, was sich aber für Webseiten leider nicht durchgesetzt hat. Für den Moment muss man die unbefriedigende Situation also hinnehmen.
Die Zertifizierungsstelle besitzt ein sog. „Wurzelzertifikat“, das sich selbst beglaubigt hat. Ein Zertifikat ist kryptologisch gesehen dabei nichts anderes als ein öffentlicher Schlüssel, der von einem anderen öffentlichen Schlüssel — oder bei Wurzelzertifikaten eben mit sich selbst — signiert wurde. Die Zertifizierungsstelle hat nun besonders Acht darauf zu geben, dass der für ihr Wurzelzertifikat passende private Schlüssel nicht in falsche Hände gerät.
Aufgabe einer Zertifizierungsstelle ist es, an sie gerichtete Zertifizierungsanfragen zu bearbeiten. Eine Zertifizierungsanfrage läuft so ab, das zunächst eine Person sich selbst einen privaten Schlüssel erzeugt. Danach erstellt sie ein Certification Request, in welchem sie ihre Daten angibt (etwa der eigene bürgerliche Name) und welches sie anschließend der Zertifizierungsstelle als „distinguished Name“ (DN, Subject) übersendet. Diese prüft nun, ob die in dem Request angegebenen Daten der Wirklichkeit entsprechen (bzw. sollte dies tun). Ist dem so, nutzt sie ihren zu ihrem Wurzelzertifikat passenden privaten Schlüssel und signiert damit das Request, welches so zum vollwertigen Zertifikat erstarkt. Dieses sendet die Zertifizierungsstelle dann an den Antragsteller zurück (und stellt ihm das Prozedere teuer in Rechnung). Von nun an kann jeder, der der Zertifizierungsstelle, sprich ihrem Wurzelzertifikat, vertraut, auch automatisch dem Inhaber des auf das ausgestellte Zertifikat passenden Schlüssels vertrauen. In Wirklichkeit erstellen Zertifizierungsstellen oftmals noch Unter- oder Zwischenzertifikate, um nicht beständig ihren hochgeheimen Wurzelschlüssel benutzen zu müssen, aber so ist der grundlegende Ablauf.
Die Zertifikate selbst sind Dateien, die einen Baum von Informationen nach dem X.509-Standard enthalten, der derartig kompliziert ist, dass selbst erfahrene Programmierer bei der Implementation Fehler mit fatalen Folgen machen. Das soll hier aber nicht Thema sein.
Neben den bereits angesprochenen Personenzertifikaten besonders relevant und für diesen Artikel maßgeblich sind Server- bzw. Dienstezertifikate, die die Inhaberschaft über einen Domainnamen im DNS beglaubigen und somit verschlüsselte Verbindungen etwa über HTTPS erlauben. Dabei wird als Namensfeld („Common Name“ im X.509-Jargon) üblicherweise der Domainname eingetragen, es ist aber auch möglich, den „Common Name“ für eine menschenlesbare Bezeichnung zu benutzen und den oder die passenden Domainnamen (es können auch mehrere sein) im Feld „subjectAltName“ unterzubringen.
OpenSSL-CA praktisch
Datei- und Verzeichnisstruktur
Es ist zweckdienlich, für die neue PKI ein eigenes Verzeichnis anzulegen.
$ cd /tmp $ mkdir pki $ cd pki
Sodann müssen einige Verzeichnisse angelegt werden, auf die das Kommando
openssl ca
später Zugriff nehmen wird, sowie einige Dateien aus
demselben Grunde:
$ mkdir certs crl newcerts private $ touch index.txt $ echo 01 > serial
Diese Informationen lassen sich mit etwas Sucherei der Manpage ca(1) entnehmen. Die Verzeichnsise und Dateien erfüllen folgende Funktionen:
- certs
- Vorgesehenes Verzeichnis für die ausgestellten Zertifikate. Man muss die Zertifikate aber noch selbst hineinschieben (und sinnvoll benennen).
- crl
- Verzeichnis für Zertifikatswiderrufe (Certificate Revocation List, CRL). Für diesen Artikel ungenutzt.
- newcerts
- Hier legt
openssl ca
ein neu ausgestelltes Zertifikat ab, welches anschließend manuell in das Verzeichnis certs/ verschoben werden muss. - private
- Hier wird der private Schlüssel der Zertifizierungsstelle liegen.
- index.txt
- Datenbank aller ausgestellten Zertifikate in Textform. Darf zu Anfang leer sein, muss aber existieren.
- serial
- Seriennummer des nächsten Zertifikats. Muss mindestens zweistellig sein, sonst verweigert OpenSSL die Arbeit.
Die Dateien index.txt
und serial
hält OpenSSL selbst auf dem
aktuellen Stand, sie müssen nur einmal initial angelegt werden.
Konfiguration von OpenSSL
Der nun folgende Teil ist schwierigste, weil die Konfigurationsdatei von OpenSSL
extrem umfangreich und vor allem unübersichtlich ist, weil sie Gebrauch
von zahlreichen Querverweisen sowie von Abschnitten mit besonderen Namen
macht, deren Dokumentation man mit der Lupe in den Manpages suchen muss.
Ausgangspunkt ist die von jeder Linux-Distribution mitgelieferte Datei
/etc/ssl/openssl.cnf
, welche jedoch für Zwecke dieser PKI so stark
angepasst wird, dass eine Kopie sich nicht lohnt. Ein Blick in diese
Datei kann aber nicht schaden. Beim Lesen dieser oder der unten
beschriebenen Datei ist dabei im Auge zu behalten, dass sie Programme
konfiguriert, die genau inverse Sichtweisen auf das Geschehen haben:
- Der Abschnitt
[req]
gibt an, wie Certificate Requests standardmäßig aussehen sollen. - Der Abschnitt
[ca]
gibt an, wie Zertifikate erstellt werden sollen (welche ja auf Certificate Requests zurückgehen!).
Bringt man diese beiden Themenkomplexe durcheinander, ist die OpenSSL-Konfiguration unverständlich.
Es wird also nunmehr eine Datei openssl.cnf
mit folgendem Inhalt
angelegt:
# Arbeite im aktuellen Arbeitsverzeichnis HOME = . RANDFILE = .rnd # Magicher Abschnitt [ca]. Wird vom Kommando "openssl ca" als # erstes eingelesen. Querverweis auf Abschnitt CA_default. [ ca ] default_ca = CA_default # Einstellungen für unsere Zertifizierungsstelle. [ CA_default ] # Pfadeinstellungen. Muss zu den Verzeichnissen passen, die # wir zuvor angelegt haben. $dir wird mit dem Wert von "dir" # ersetzt, welcher hier das aktuelle Arbeitsverzeichnis ist. # Die CRL-Optionen nutzen wir in unserem Setup nicht. dir = . certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/cacert.pem serial = $dir/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/cakey.pem RANDFILE = $dir/private/.rand # WICHTIGE OPTION. Diese Option gibt an, welche X.509-Erweiterungen # *standardmäßig* in signierte Zertifikate eingebaut werden sollen, # auch dann, wenn sie nicht angefordert wurden. Mit der Kommando- # zeilenoption "-extensions" kann ein anderer als der hier ange- # gebene Abschnitt gewählt werden. x509_extensions = v3_ca # Honoriere die vom Certification Request angegebenen Werte. # Ohne diese Option werden nur die oben genannten x509_extensions # beglaubigt. Gibt es Kollisionen, geht mit "copyall" (wie hier) # das vor, was im Certification Request genannt ist; mit "copy" # geht das vor, was hier in der Konfiguration steht. copy_extensions = copyall # Aus originaler openssl.cnf übernommen name_opt = ca_default cert_opt = ca_default # Standardmäßig über 1 Jahr zertifizieren default_days = 365 default_crl_days= 30 default_md = default preserve = no # Welche Werte zwingend vorhanden sein müssen, regelt die sog. # "Policy". policy = policy_match # Die oben referenzierte Policy wird hier definiert. # "match" bedeutet, dass das zu Certificate Request # dem Wert des CA-Zertifikats entsprechen muss, "optional" # bedeutet, der Schlüssel ist optional, "supplied" bedeutet, # dass der Schlüssel vorhanden sein muss, sein Wert jedoch # keine Rolle Spielt. [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional ######################################## # Magischer Abschnitt [req]. # Wird von "openssl req" als erstes eingelesen, # wenn ein neues Certificate Request erstellt werden # soll. [ req ] # 4096 Bit sollten sicher sein. default_bits = 4096 default_keyfile = privkey.pem # Querverweis auf Abschnitt, der den DN definiert. distinguished_name = req_distinguished_name # Kopiert attributes = req_attributes string_mask = utf8only # Welche X.509-Erweiterungen standardmäßig angefordert werden sollen. # "x509_extensions" kommt nur bei Selbstignierung zum Tragen (also # dann, wenn ein Wurzelzertifikat erzeugt wird). Ansonsten greift # "req_extensions", was somit der Regelfall ist. x509_extensions = v3_ca req_extensions = server_cert # Der standardmäßig vorgeschlagene DN für neue Certification # Requests. Die Felder sind recht selbsterklärend. # Beachte hierzu aber https://superuser.com/questions/512673/#comment1084446_641055 [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = DE countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Baden-Württemberg localityName = Locality Name (eg, city) localityName_default = Stuttgart 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Ich AG commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAdress_default = ich@example.com emailAddress_max = 64 # Kopiert [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name ######################################## # Es folgen die Standarderweiterungs- # sets. Diese können per Kommandozeilen- # option "-extensions" ausgewählt werden. ######################################## ######################################## # Nutzerzertifikat [ usr_cert ] # Keine Unter-CA erlauben. basicConstraints=CA:FALSE # Nutzungstyp. "nsCertType" ist ein älterer Standard als "keyUsage", # es schadet nicht, beides anzugeben. Hier: Reiner Nutzer, d.h. # vor allem kein Ausgeben als Server zuzulassen. nsCertType = client, email keyUsage = nonRepudiation, digitalSignature, keyEncipherment ######################################## # Serverzertifikat # Ganz ähnlich wie schon oben, nur # mit Serverstatus. [ server_cert ] basicConstraints = CA:FALSE nsCertType = server extendedKeyUsage = serverAuth keyUsage = digitalSignature, keyEncipherment ######################################## # CA-Zertifikat # Dies darf nur für solche Zertifikate verwandt werden, # die Unterzertifikate beglaubigen können sollen dürfen! [ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = CA:true keyUsage = cRLSign, keyCertSign nsCertType = sslCA, emailCA
Erzeugung der Zertfikate
Wurzelzertifikat
Hat man diese grundlegenden Prozesse hinter sich, wird der private
Schlüssel für das Wurzelzertifikat generiert. Dieser wird dabei in der
Datei private/cakey.pem
abgelegt. Wer mag, kann zusätzlich noch
strenge Zugriffsrechte an die Datei anlegen. Im folgenden Beispiel wird
ein 4096 Bit großer RSA-Schlüssel erzeugt; allgemein empfohlen werden
wenigstens 2048 Bit.
$ cd private $ openssl genrsa -out cakey.pem 4096 Generating RSA private key, 4096 bit long modulus ...................................................................................................++ ..............................................................................++ e is 65537 (0x10001)
Nun erzeugt man das dazugehörige Wurzelzertifikat. Dabei wird mithilfe
der Kommandozeilenoption -extensions v3_ca
explizit die Erstellung
eines Zertifikats mit CA-Fähigkeiten angefordert, welche für ein
Wurzelzertifikat unabdingbar sind. Es handelt sich dabei um nichts
anderes als einen Verweis auf den entsprechenden Abschnitt in der oben
angelegten Konfigurationsdatei, der zusätzlich zum Abschnitt [req]
eingelesen wird und dessen Option req_extensions
überschreibt.
Tatsächlich sollte es auch ohne -extensions v3_ca
gehen, weil der
alternative Konfigurationsparameter x509_extensions
greifen sollte,
aber es wird klarer, wie die Technik funktioniert, wenn man den
Parameter explizit auf der Kommandozeile angibt.
$ cd .. $ openssl req -new -x509 -days 3650 \ -extensions v3_ca -key private/cakey.pem \ -out cacert.pem -config openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [DE]: State or Province Name (full name) [Baden-Württemberg]: Locality Name (eg, city) [Stuttgart]: Organization Name (eg, company) [Ich AG]: Common Name (e.g. server FQDN or YOUR name) []:Test MAster-CA Email Address []:
Dieses Zertifikat sollte man nun kontrollieren. Besonderes Augenmerk ist auf die Feststellung zu verwenden, ob die X.509-Erweiterungen korrekt gesetzt wurden und mit denen in der Konfigurationsdatei übereinstimmen. Es sollte etwa so aussehen:
$ openssl x509 -in cacert.pem -text Certificate: Data: Version: 3 (0x2) Serial Number: 16014081171043375726 (0xde3d71fa944fda6e) Signature Algorithm: sha256WithRSAEncryption Issuer: C=DE, ST=Baden-W\xC3\x83\xC2\xBCrttemberg, L=Stuttgart, O=Ich AG, CN=Test MAster-CA Validity Not Before: Nov 2 20:09:35 2015 GMT Not After : Oct 30 20:09:35 2025 GMT Subject: C=DE, ST=Baden-W\xC3\x83\xC2\xBCrttemberg, L=Stuttgart, O=Ich AG, CN=Test MAster-CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: [...] Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Authority Key Identifier: keyid:4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Basic Constraints: CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign Netscape Cert Type: SSL CA, S/MIME CA Signature Algorithm: sha256WithRSAEncryption [...] -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE-----
Damit steht das Wurzelzertifikat und es kann nunmehr daran gegangen
werden, ein Zertifikat für einen Webserver auzustellen. Als Beispiel
wird hier zunächst ein einfaches Serverzertifikat für die Domain
example.com
ausgestellt.
Normales Webserver-Zertifikat
Wie zuvor beginnt man mit dem privaten Schlüssel.
$ openssl genrsa -out example.com.privatekey.pem 4096 Generating RSA private key, 4096 bit long modulus ....................................................++ ..++ e is 65537 (0x10001)
Nun wird ein Certification Request erstellt. Dabei darauf achten, dass
im [req]
der openssl.cnf auch wirklich ein server_crt
erstellt wird.
$ openssl req -new -out example.com.req \ -key example.com.privatekey.pem -config openssl.cnf You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [DE]: State or Province Name (full name) [Baden-Württemberg]: Locality Name (eg, city) [Stuttgart]: Organization Name (eg, company) [Ich AG]: Common Name (e.g. server FQDN or YOUR name) []:example.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Kontrollieren, ob das Certificate Request den Anforderungen entspricht, also insbesondere, ob die X.509-Erweiterungen korrekt angefordert werden:
$ openssl req -in example.com.req -text [...] Requested Extensions: X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment [...]
Stimmt alles, kann nunmehr von unserer CA signiert werden. Man beachte
hier, wie openssl ca
zunächst den magischen Abschnitt [ca]
einliest
und so den öffentlichen (Zertifikat) und privaten Schlüssel der CA
findet. Unbedingt zu kontrollieren ist dabei, ob die nun von
openssl ca
vorgeschlagenen X.509-Extensions mit den eigenen
Erwartungen übereinstimmen. Optionen wie copy_extensions
in der
Konfiguration führen zuweilen zu unerwarteten Ergebnissen, bei denen
auch schonmal ein nsCertType von „client“ festgelegt wird bei
gleichzeitigem extendedUsage als „TLS Web Server“ (weil ersterer im
Request nicht enthalten war). Also dreimal kontrollieren, bevor man die
Nachfrage bestätigt.
$ openssl ca -config openssl.cnf \ -out example.com.cert.pem -infiles example.com.req Using configuration from openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Nov 2 20:27:36 2015 GMT Not After : Nov 1 20:27:36 2016 GMT Subject: countryName = DE stateOrProvinceName = Baden-W\C3\BCrttemberg organizationName = Ich AG commonName = example.com X509v3 extensions: X509v3 Subject Key Identifier: FF:C6:2F:16:FE:A7:FB:32:CE:BB:13:FC:23:5B:80:68:8F:A0:E4:A5 X509v3 Authority Key Identifier: keyid:4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment Certificate is to be certified until Nov 1 20:27:36 2016 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Zertifikat noch einmal kontrollieren:
$ openssl x509 -in example.com.cert.pem -text [...] X509v3 extensions: X509v3 Subject Key Identifier: FF:C6:2F:16:FE:A7:FB:32:CE:BB:13:FC:23:5B:80:68:8F:A0:E4:A5 X509v3 Authority Key Identifier: keyid:4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment [...]
Perfekt. Das Zertifikat ist fertig. Die Dateien example.com.cert.pem
und newcerts/01-example.com
sind im übrigen identisch; letzte wird
automatisch erzeugt, erstere ist das Ergebnis der Kommandozeilenoption
-out
. Man hätte auch darauf verzichten können.
Noch in den Verzeichnissen aufräumen:
$ mv newcerts/01.pem certs/01-example.com $ rm example.com.req $ mkdir /tmp/distribute-example.com $ mv example.com.privatekey.pem /tmp/distribute-example.com $ mv example.com.cert.pem /tmp/distribute-example.com $ cp cacert.pem /tmp/distribute-example.com
Das Verzeichnis /tmp/distribute-example.com
enthält nunmehr alles, was
ein Webserver-Administrator benötigt: Sein privater Schlüssel, das
beglaubigte Zertifikat, und das CA-Zertifikat.
Zertifikat mit besonderen Anforderungen
Wie schon eingangs erwähnt gibt es zuweilen Situationen, die nicht mit
den Standardwerten aus der openssl.cnf abgedeckt werden können. So
werden etwa an XMPP-Server-Zertifikate eine
ganze
Reihe
Anforderungen
gestellt. Ist man
mit einer solchen Anforderung konfrontiert, empfiehlt sich das Anlegen
einer separaten Konfigurationsdatei allein für die Erstellung des
zugehörigen Certification Requests. Für ein
XMPP/Jabber-Server-Zertifikat könnte eine Datei xmpp.cnf
etwa so
aussehen:
HOME = . RANDFILE = rand oid_section = new_oids # Define shortcuts we use later in the subjectAltName [new_oids] xmppAddr = 1.3.6.1.5.5.7.8.5 SRVName = 1.3.6.1.5.5.7.8.7 # Special name [req] as per req(1) manpage. [req] default_bits = 4096 default_keyfile = privkey.pem distinguished_name = xmpp_server_req_dn req_extensions = xmpp_server_req_usage x509_extensions = xmpp_server_req_usage prompt = no [xmpp_server_req_dn] countryName = DE stateOrProvinceName = Baden-Württemberg localityName = Stuttgart organizationName = Ich AG commonName = XMPP-Server der Ich AG emailAddress = admin@example.com [xmpp_server_req_usage] basicConstraints = CA:FALSE nsCertType = server extendedKeyUsage = serverAuth keyUsage = digitalSignature, keyEncipherment subjectAltName = @xmpp_server_req_altnames [xmpp_server_req_altnames] DNS.0 = example.com DNS.1 = *.example.com otherName.0 = xmppAddr;FORMAT:UTF8,UTF8:example.com otherName.1 = SRVName;IA5STRING:_xmpp-client.example.com otherName.2 = SRVName;IA5STRING:_xmpp-server.example.com
In der Anwendung sieht das dann so aus; man beachte beim zweiten Befehl
die Angabe der neu angelegten Konfigurationsdatei xmpp.cnf
:
$ openssl genrsa -out xmpp.privatekey.pem 4096 $ openssl req -new -out xmpp.req \ -key xmpp.privatekey.pem -config xmpp.cnf $ openssl req -in xmpp.req -text [...] Requested Extensions: X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Subject Alternative Name: DNS:example.com, DNS:*.example.com, othername:<unsupported>, othername:<unsupported>, othername:<unsupported> [...] $ openssl ca -config openssl.cnf \ -out xmpp.cert.pem -infiles xmpp.req Using configuration from openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 2 (0x2) Validity Not Before: Nov 2 20:43:44 2015 GMT Not After : Nov 1 20:43:44 2016 GMT Subject: countryName = DE stateOrProvinceName = Baden-W\C3\BCrttemberg organizationName = Ich AG commonName = XMPP-Server der Ich AG emailAddress = admin@example.com X509v3 extensions: X509v3 Subject Key Identifier: 10:13:C1:E9:3D:D5:0E:A7:AF:BB:62:BA:E3:D4:36:47:AA:70:20:22 X509v3 Authority Key Identifier: keyid:4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Subject Alternative Name: DNS:example.com, DNS:*.example.com, othername:<unsupported>, othername:<unsupported>, othername:<unsupported> Certificate is to be certified until Nov 1 20:43:44 2016 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated $ openssl x509 -in xmpp.cert.pem -text [...] X509v3 extensions: X509v3 Subject Key Identifier: 10:13:C1:E9:3D:D5:0E:A7:AF:BB:62:BA:E3:D4:36:47:AA:70:20:22 X509v3 Authority Key Identifier: keyid:4A:5A:70:B4:C6:FF:41:BD:72:76:E9:82:77:FB:6E:DE:00:61:86:8C X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Subject Alternative Name: DNS:example.com, DNS:*.example.com, othername:<unsupported>, othername:<unsupported>, othername:<unsupported> [...] $ mkdir /tmp/distribute-xmpp $ mv xmpp.cert.pem /tmp/distribute-xmpp $ mv xmpp.privatekey.pem /tmp/distribute-xmpp $ mv newcerts/02.pem certs/02-xmpp.pem $ rm xmpp.req $ mv xmpp.cnf /var/backup
So erhält man dann auch ein Zertifikat mit dem etwas schwierigen subjectAltName.
Abschluss
Der Artikel basiert zu wesentlichen Teilen auf
dieser
Anleitung für FreeBSD, erläutert aber schwerer verständliche
Punkte wie insbesondere die OpenSSL-Konfiguration erheblich
ausführlicher. Es wäre wünschenswert, wenn das OpenSSL-Projekt mehr und
vor allem reichlich kommentierte Beispielkonfigurationen für
verschiedene Anwendungsfälle bereitstellte, und noch besser wäre es, die
Konfigurationen für drei völlig unterschiedliche Programme — req
,
x509
und ca
— auch optisch-funktional in unterschiedlichen
Konfigurationsdateien unterzubringen. Am besten allerdings wäre die
Verbesserung der Dokumentation.