Bei Webservern wie Apache(2) mit wird SSL oder TLS die Hybride Verschlüsselung zur Absicherung des Datenverkehrs eingesetzt. Dazu werden X.509-Zertifikate eingesetzt.
Durch das Projekt zur Zertifikatstransparenz (Certificate Transparency ‒ CT) ist leicht überprüfbar welche Zertifizierungsstelle für eine Domain Zertifikate ausstellt: https://crt.sh/ .
Dateiendung | Format & Einsatz | Informationen anzeigen |
---|---|---|
CER | DER- oder Base64-kodiertes Zertifikat | |
CRT | DER- oder Base64-kodiertes Zertifikat | openssl x509 -in $crt -text -noout |
CSR | Base64-kodierte Zertifikatsanforderung | openssl req -text -noout -verify -in $csr |
DER | DER-kodiertes Zertifikat | openssl x509 -inform DER -text -in $datei |
P12 / PFX | PKCS#12 - kann öffentliche Zertifikate und private Schlüssel (Kennwort-geschützt) enthalten - z.B. bei S/MIME anschauen: gcr-viewer | openssl pkcs12 -in $p12datei -info |
P7B / P7C | PKCS#7-signierte Datenstruktur ohne Dateninhalt - nur mit Zertifikat(en) oder Zertifikatsperrliste(n) | |
PEM | Base64-kodiertes Zertifikat - umschlossen von „—–BEGIN CERTIFICATE—–“ und „—–END CERTIFICATE—–“ | siehe crt |
JKS | Java keystore bei Applikationsservern | java certool oder keystore explorer |
Die TLS-Erweiterung „Server Name Indication (SNI)“ ist mittlerweile Standard, alle Zertifikate sollten die DNS-Namen im SNI-Feld aufführen. Mittlerweile werden Zertifikate ohne SNI als unsicher eingestuft.
Siehe auch: Man-in-the-middle Attacken gegen SSL.
Die Anleitung ist für Apache und mod_ssl gedacht.
Eine Zertifizierungsanforderung (CSR)1) ist eine Datei, die die Antragsdaten sowie den öffentlichen Schlüssel enthält.
Der private Schlüssel bleibt auf dem Server (hoffentlich) geheim und kann auch mit einer Passphrase geschützt werden, in diesem Fall muss man allerdings bei Neustart des Webservers immer die Passphrase angeben (sonst startet der Webserver nicht).
Dazu erstellen wir ein Schlüsselpaar bestehend aus privatem Schlüssel und öffentlicher Zertifizierungsanforderung (CSR). Entweder mit 2048 Bit:
openssl req -new -nodes -sha256 -keyout dateiname.key -out dateiname.csr -newkey rsa:2048
oder mit 4096 Bit Schlüssellänge:
openssl req -new -nodes -sha256 -keyout dateiname.key -out dateiname.csr -newkey rsa:4096
.
PSW verlangt mindestens den Common Name, Organisation, Ort, Bundesland und Ihr Land im CSR. Es bietet sich an den Dateinamen so zu wählen, daß man ihn später eindeutig der Webseite zuordnen kann.
Der Befehl erzeugt also zwei Dateien:
Bei der Erstellung der Zertifizierungsanforderung werden Sie nach einigen Details gefragt, die neben dem öffentlichen Schlüssel in den CSR-Datei aufgenommen werden und diesen eindeutig machen. Einige Felder sind optional (unwichtige Felder) und haben einen Standardwert (diesen kann man mit der Eingabetaste übernehmen oder man gibt Sie einen Punkt (.) ein, wenn dieses Feld leer bleiben soll)
Teil des Zertifikats | Erklärung |
---|---|
Country Name (2 letter code) [AU]: DE | hier das Länderkürzel eingeben, z.B. DE |
State or Province Name (full name) [Some-State]: Berlin | hier das Bundesland eingeben, z.B. Berlin |
Locality Name (eg, city) []: Berlin | hier den Ort eingeben |
Organization Name (eg, company) [Internet Widgits Pty Ltd]: FIRMENNAME | hier den Firmennamen / Organisationsnamen / Vor- und Zunamen ein, je nachdem, was passt |
Organizational Unit Name (eg, section) []: IT | hier kann man eine Abteilung eingeben, dieses Feld kann aber auch leer bleiben |
Common Name (eg, YOUR name) []: www.DOMAIN.de | hier muss die geschützte Seite mit vollständigem Domainnamen enthalten sein. Also z.B. www.DOMAIN.de . Das im Browser vorangestellte https:// wird nicht angegeben. Genauso sind Unterverzeichnisse und einzelne Dateien bereits enthalten und werden nicht angegeben. |
Email Address []: info@domain.de | hier gibt man seine E-Mail-Adresse ein |
Gegebenenfalls werden Sie nach folgenden 'extra'-Angaben gefragt
A challenge password []: An optional company name []:
bitte immer leer lassen.
Die Zertifikatsanfrage wurde nun erstellt. Jetzt muss man nur noch dateiname.csr in einem Editor öffnen und in die Zwischenablage kopieren (z.B. mit cat dateiname.csr
) und den Inhalt in das vorgesehene Feld im Bestellprozess kopieren. Das sieht dann in etwa so aus:
-----BEGIN CERTIFICATE REQUEST----- (...) -----END CERTIFICATE REQUEST-----
Damit verschickt man die Zertifikatsanfrage an den Zertifikatsaussteller der dann das eigentliche Zertifikat ausstellt.
Vom privaten Schlüssel (dateiname.key) unbedingt ein Backup erzeugen, bei Verlust oder Diebstahl ist das Zertifikat nicht mehr sic her und damit wertlos.
Ein selbst signiertes Zertifikat ist schnell erstellt und bietet auch sichere Verschlüsselung.
openssl genrsa -out server.key -aes256 2048
Passphrase eingeben, der private Schlüssel ist dann in server.key.
openssl req -new -x509 -days 1460 -key server.key -out server.crt
Common Name sollte auf den Servernamen lauten, sonst gibt es noch eine zusätzliche Fehlermeldung beim Benutzer
Allerdings ist der große Nachteil, das der Benutzer 2 Fehlermeldungen sieht:
Die zwei nervigen Meldungen mögen für private Seiten ok sein, für Unternehmensseiten geht es definitiv nicht. Der Grund ist das die Benutzer von der Fehlermeldung abgeschreckt werden und der demonstrierte Geiz auch kein gutes Licht auf die Firma wirft.
Wenn der private Schlüssel eine Passphrase hat muss bei jedem Neustart des Webservers die Passphrase eingegeben werden! Deshalb ist es oft gewünscht die Passphrase zu entfernen:
openssl rsa -in /etc/apache2/server.key -out /etc/apache2/server_neu.key
#!/bin/sh key="myDOMAIN.key" csr="myDOMAIN.csr" crt="myDOMAIN.crt" intermediate="myDOMAIN.cabundle" # check key: openssl rsa -in $key -noout -check # print csr: # openssl req -text -noout -verify -in $csr # print crt: # openssl x509 -in $crt -text -noout long_modulos_csr=$(openssl req -noout -modulus -in $csr | openssl md5) long_modulos_crt=$(openssl x509 -noout -modulus -in $crt | openssl md5) long_modulus_key=$(openssl rsa -noout -modulus -in $key | openssl md5) if [[ $long_modulos_csr == $long_modulus_key ]]; then echo "$csr matches $key" else echo "$csr does NOT match $key !!!" fi if [[ $long_modulos_crt == $long_modulus_key ]]; then echo "$crt matches $key" else echo "$crt does NOT match $key !!!" fi # checks if chain is complete - CA must be present in local system: openssl verify -untrusted $intermediate -untrusted $crt # check for a given CA: # RootCert="rootcert.crt" # openssl verify -CAfile $RootCert -untrusted $intermediate $crt