====== SSL-Zertifikate ====== Bei [[server:Webserver|Webservern]] wie [[apache:Apache]](2) mit wird [[netzwerke:ssl und tls|SSL oder TLS]] die [[security:verschlüsselung#hybride verschlüsselung|Hybride Verschlüsselung]] zur Absicherung des Datenverkehrs eingesetzt. Dazu werden [[wpde>X.509]]-Zertifikate eingesetzt. Durch das [[https://www.certificate-transparency.org/|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 [[security:email-verschlüsselung#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 [[http://keystore-explorer.org/index.html|keystore explorer]] | Die TLS-Erweiterung "[[wpde>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: [[netzwerke:ssl und tls#Man-in-the-middle Attacken gegen SSL]]. ===== Anforderungen an X.509 Zertifikate ===== - Subject Alternativ Name (SubjectAltName / SAN): RFC 2818 sagt, dass wenn SubjectAltName existiert, man ihn nehmen MUSS. (Der CN ist nicht obsolet aber X.509 v3-Zertifikate **müssen** einen SubjectAltName haben) - **Zertifikate dürften nicht mehr mit SHA-1 signiert werden**. Diese Zertifikate werden als unsicher eingestuft. ===== Geheimen Schlüssel und Zertifizierungsanforderung (CSR) erstellen ===== Die Anleitung ist für [[apache:Apache]] und mod_ssl gedacht. Eine Zertifizierungsanforderung (CSR)((Base64-kodiert)) 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 [[server:Webserver|Webservers]] immer die Passphrase angeben (sonst startet der [[server:Webserver]] nicht). - Erstellen der CSR-Datei: 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. [[http://www.psw.net/ssl-zertifikate.cfm|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: - Die Datei mit der Endung key enthält den privaten Schlüssel, geben Sie diese Datei daher nicht an Fremde weiter. Bitte erstellen Sie auf jeden Fall ein Backup Ihres privaten Schlüssels, da es keine Möglichkeit der Wiederherstellung nach einem Verlust gibt. Der private Schlüssel dient als Grundlage der Zertifizierungsanforderung (CSR) und damit auch als Grundlage des Zertifikates. - Die Datei mit der Endung csr ist die Zertifikatsanforderung (enthält den öffentlichen Schlüssel) 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 (self-signed) Zertifikat erstellen ===== 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: - weil die Seite kein Zertifikat von einer anerkannten Zertifizierungsstelle (CA) hat und - nicht authentifiziert werden kann ("Der Aussteller des Zertfikates kann nicht identifiziert/verifiziert werden o.ä.). 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. ===== Passphrase entfernen ===== Wenn der private Schlüssel eine Passphrase hat muss bei jedem Neustart des [[server:Webserver|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 ===== SSL-Zertifikat testen ===== * [[http://demo.a-sit.at/it_sicherheit/ssl_check/index.html|SSL-Test Client/Server]] ==== testssl.sh ==== https://testssl.sh/| ==== openssl Shellskript ==== #!/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