OpenSSL nicht nur mit dem Raspberry Pi oder wie können Zertifikate selbst signiert werden mit eigener selbst-signierter Root-CA?

OpenSSL ist ein in C entwickeltes Kryptographiewerkzeug für das Secure Socket Layer (SSL). Es enthält das Mehrzweck-Befehlszeilenwerkzeug /usr/bin/openssl. Das Programm eignet sich für kryptographische Operationen wie:

  • Erzeugung von RSA-, DH- und DSA-Schlüssel-Parametern
  • Erzeugung von X.509-Zertifikaten, CSRs und CRLs
  • Berechnung von kryptographischen Einweg-Hashfunktionen
  • Ver- und Entschlüsselung mit Chiffren
  • Prüfung von SSL-/TLS-Clients und -Servern
  • Bearbeitung von S/MIME-signierter oder verschlüsselter E-Mail

Welche Version ist auf dem Raspberry Pi installiert? Ein

apt-cache policy openssl

liefert folgende Ausgabe:

oder ein
openssl version liefert:

OpenSSL 1.1.1d 10 Sep 2019

Für die neue Version 3.0 gibt es schon seit Juli ein Release-Kandidat, aber noch kein Debian Package. Dann arbeiten wir mal mit der installierten Version, und erstellen uns zuerst mal einen private Key und dann ein selbst signiertes Zertifikat.

Wir können die Hilfe des OpenSSL Programms wie folgt ausgeben:

openssl help

Wir bekommen diese Anleitung:

So, nun wollen wir aber einen 2048-Bit RSA privaten Key, auf der Kommandozeile erstellen als Grundlage für die Zertifikate.
Wir erstellen uns zuerst ein eigenes neues leeres Verzeichnis und wechseln dahin:

mkdir zertifikate
cd zertifikate

Den Namen der Ausgabe-Datei (hier wenzlaff-klartext.key) wird hinter -out angegeben, den können wir natürlich durch einen eigenen Domain.key Name ersetzen. Wir generieren also eine RSA Key der Größe 2048-Bit und das ganze unverschlüsselt im Klartext:

openssl genrsa -out wenzlaff-klartext.key 2048

Nach ca. 3 Sekunden …

erhalten wir nun den privaten key in der Datei: wenzlaff-klartext.key.
Denn können wir uns mal ausgeben mit

cat wenzlaff-klartext.key

Mit dem Parameter -des3 wird der Key verschlüsselt. Wir erzeugen uns nun einen verschlüsselten privaten Key, wieder mit 2048-Bit und RSA:

openssl genrsa -des3 -out wenzlaff.key 2048

Jetzt werden wir nach einem Passwort für den privaten Key gefragt. Dies müssen wir zweimal eingeben. Mit diesem wird dann der Key verschlüsselt. Also gut merken, wir brauchen ihn nachher noch.

Ausgabe:

Wenn wir uns den Key wieder ausgeben mit cat wenzlaff.key

Nun sehen wir in den ersten 3 Zeilen, das der Key mit DES-EDE3-CBC verschlüsselt worden ist. Diesen privaten Key müssen wir sicher aufbewahren und geheim halten.

Wir erstellen nun mit Hilfe des privaten Key eine Zertifikatsignierungsanforderung (Certificate Signing Request (CSR) oder Certification Request). Die CSR-Datei ist ein digitaler Antrag oder Formular, das neben den Antragsdaten auch einen öffentlichen Schlüssel bzw. Zertifikat (aus dem privaten Key) enthält.

Dieser CSR könnte dann zu einer Registrierungsstelle zur Überprüfung gesendet werden. Wenn die Antragsdaten und das Zertifikat zueinander passend und io sind, kann das Ergebnis an die Zertifizierungstelle (certification authority) gegeben werden. Diese signiert nun mit ihren privaten CA Schlüssel das Zertifikat, und stellt damit ein neues öffentliches Zertifikat aus. Damit wurde nun der öffentliche Schlüssel doppelt signiert, einmal von einem selbst und einmal von der CA. Dazu später mehr.

Das wollen wir aber erstmal nicht machen. Wir wollen einfach unser Zertifikat mit unseren privaten Key selbst signieren. Es kann genauso wie ein Zertifikat das von einer CA signiert wurde verwendet werden. Mit dem Unterschied, das eine warnung kommt, die besagt das dem Zertifikat nicht vertraut werden kann. Das ist aber für unsere Zwecke erst mal ok.

Wir erzeugen unsere CSR-Datei mit diesem Befehl:

openssl req -key wenzlaff.key -new -out wenzlaff.csr

Wir müssen dann einige Antragsdaten beantworten. Die wichtigste ist der Common Name, dort muss der „Fully Qualified Domain Name“, kurz FQDN eingetragen werden. Er bezeichnet die vollständige und eindeutige Adresse einer Internetpräsenz. Z.B. www.wenzlaff.de oder www.kleinhirn.eu. Er setzt sich aus dem Hostname und der Domain zusammen und wird verwendet, um spezifische Hosts im Internet zu lokalisieren und mittels Namensauflösung aufzurufen. Auf dem Raspberry Pi oder dem Mac kann man den Host z.B. mit

hostname -f

abfragen. Dies ist der Ablauf, erst das Passwort von dem privaten Key, den wir uns gemerkt haben eingeben und dann wie oben beschrieben:

Es wurde eine wenzlaff.csr (Base64-kodierter Zertifizierungsanfrage des öffentlichen Schlüssels, plus weitere Metadaten des Besitzers, an eine CA, umschlossen von „—–BEGIN CERTIFICATE REQUEST—–“ und „—–END CERTIFICATE REQUEST—–“ erzeugt. Dies kann mit cat wenzlaff.csr angeschaut bzw. ausgegeben werden.

Nun haben wir in der Datei wenzlaff.csr die CSR-Anforderung und den public Key.

Wir erzeugen uns ein selbst signiertes Zertifikat das ein Jahr gültig sein soll, mit unseren privaten Key (wenzlaff.key und Passwort) und der CSR-Datei (wenzlaff.csr) mit:

openssl x509 -signkey wenzlaff.key -in wenzlaff.csr -req -days 365 -out wenzlaff.crt

Ausgabe, nach der Passwort eingabe des privaten Keys:

Das Ergebnis bzw. das Selbst-Signierte-Zertifikat finden wir dann in der wenzlaff.crt Datei.

Das Zertifikat können wir uns wie folgt als Text ansehen:

openssl x509 -text -noout -in wenzlaff.crt

Ausgabe:

Wir sehen nun die Serial Number und auch die Antragsdaten unter Issuer. Unter Validity finden wir die Gültigkeit des Zertifikats von einem Jahr. Unter DNS finden wir den übergebenen FQDN.

Wir können aber auch eine eigene selbst-signierte CA nutzen, um unseren CSR mit dieser Root CA zu signieren. Diese Selbst-Signierte-Root CA Zertifikat können wir dann lokal im Browser installieren.

Das hört sich ja gut an.

Also erste eine eigenen Root CA erstellen und selbst signieren und dann unser CSR signieren.

Zuerst brauchen wir einen privaten RSA Key (2048-Bit), der 5 Jahre (-days 1825) gültig sein soll (rootCA.key) und das Selbst-Signierte-Root-CA-Zerfifikat (rootCA.crt)

openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt

Ausgabe:

Zum signieren des csr mit der Root-CA brauchen wir eine Konfigurations-Datei mit Namen wenzlaff.ext und folgenden Inhalt:

Der DNS.1 Eintrag muss den Domain Name der Webseite enthalten.
Nun können wir unseren wenzlaff.csr Antrag mit der Root-CA-Zertifikat für ein Jahr und den privaten Key signieren:

openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in wenzlaff.csr -out wenzlaff.crt -days 365 -CAcreateserial -extfile wenzlaff.ext
Ausgabe:

Das Ergebnis, das selbst signierte CSR steht im wenzlaff.crt File und ist nun von einer eigenen Root CA (selbst signiert) signiert. Cool, das wollen wir uns gleich mal anschauen:

openssl x509 -text -noout -in wenzlaff.crt

Ergebnis:

In Zeile 7 sehen wir die Signatur der eigenen Root-CA die das Zertifikat signiert hat. Und in Zeile 11 mein Zertifikat.

Und auch gleich noch in das DER-Format umwandeln. DER steht für Distinguished Encoding Rules. Bei einer .der-Datei handelt es sich um die binäre Form der Base64-kodierten .pem-Datei. Neben .der können entsprechende Zertifikate auch mit der Endung .cer existieren, vor allem unter Windows. Neben Windows kommen Zertifikate im DER-Format auch unter Java zum Einsatz. Dieses Format unterstützt die Speicherung eines einzelnen Zertifikats. Private Schlüssel oder der Zertifizierungspfad können mit diesem Format nicht gespeichert werden.

openssl x509 -in wenzlaff.crt -outform der -out wenzlaff.der

Und auch in das PFX oder P12 Format. Der PKCS#12-Standard ist in RFC 7292 beschrieben. Das binäre Format kann neben dem Zertifikat auch alle Zertifikate des Zertifizierungspfads und zudem den privaten Schlüssel enthalten. Alles in einer Datei. Darüber hinaus ist es möglich die  Datei passwortgeschützt zu speichern. Als Dateiendungen kommen .pfx oder .p12 zum Einsatz. Dieses Format wird oft zum Import und Export von Zertifikaten und privaten Schlüsseln unter Windows (MSIIS) verwendet.

Es wird der private Key und das Zertifikate zusammen in ein PKCS12 File geschrieben.

openssl pkcs12 -inkey wenzlaff.key -in wenzlaff.crt -export -out wenzlaff.pfx

oder mit p12 Extension.

Für den Import im eigenen E-Mail Client fügt man den privaten Schlüssel und das signiertes Zertifikat zu einer PKCS12-Datei „wenzlaff.p12″ zusammen. Diese passwortgeschützte Datei kann in allen E-Mail Clients importiert werden und sollte sicher verwahrt werden.

openssl pkcs12 -inkey wenzlaff.key -in wenzlaff.crt -export -out wenzlaff.p12

Oder wir wandeln von PFX nach PEM, da werden wir auch nach dem Passwort gefragt, und erhalten eine druckbare PEM Datei mit dem privaten Key!

openssl pkcs12 -in wenzlaff.pfx -out wenzlaff.pem -nodes

Wenn wir uns das Zertifikat aus der wenzlaff.pem Datei mit cat wenzlaff.pem anschauen, sehen wir das Zertifikat, die Antragsdaten und den privaten Key:

Das PEM-Format ist sehr beliebt und wird auch häufig von Zertifizierungsstellen verwendet. Der Name PEM bedeutet Privacy Enhanced Mail. Es ist Base64 kodiert und kann neben dem reinen Zertifikat auch Intermediate-Zertifikate, Root-CAs und private Schlüssel beinhalten. Apache-Server (/etc/ssl/certs) und Open-Source-Software setzen oft auf das PEM-Format. Die Dateierweiterung .pem kommt meist zum Einsatz, wenn sowohl Zertifikate und der Privatschlüssel in einer Datei gespeichert werden. Darüber hinaus hat das PEM-Format auch noch folgende Dateiendungen: .cert, .cer, .crt oder .key.

So, das wars mit RSA nun das ganze mit eliptische Kurven. Welche gibt es auf dem System?

openssl ecparam -list_curves

Ausgabe der 88 Möglichkeiten in einer schönen Liste:

Welchen verwenden wir? secp384r1 das entspricht dann 7680 Bit größe in RSA oder secp521r1 mit 521-Bit, das währe dann 15360 Bits in RSA.

Aber nicht mehr heute, mit Java hatte ich das hier beschrieben oder für den Raspberry Pi hier

PS: Natürlich werden alle hier veröffentlichen private/public Keys gelöscht und nicht verwendet 😉 Das währe dann ja auch kein privater Key 😉