OpenSSL ist das meistgenutzte Kryptografie-Toolkit der Welt und bildet das Fundament für HTTPS, VPNs, E-Mail-Verschlüsselung und digitale Zertifikate. Version 3.5.5 LTS (Long-Term-Support bis April 2030) ist der empfohlene Stand für Produktivumgebungen, während 4.0.0 (veröffentlicht am 14. April 2026) die neuesten Post-Quantum-Algorithmen ML-KEM und ML-DSA mitbringt. Dieses Tutorial führt dich in 12 konkreten Schritten durch die wichtigsten OpenSSL-Operationen: von der Schlüsselgenerierung über den Aufbau einer eigenen Certificate Authority bis hin zur TLS-1.3-Verbindungsprüfung.

Das Keyword “openssl” wird in Deutschland 5.400-mal pro Monat gesucht, bei niedrigem Wettbewerb. Der Grund: Viele Entwickler und Systemadministratoren kennen die grundlegenden Befehle, verstehen aber nicht, was dahintersteckt. Dieses Tutorial schließt diese Lücke mit produktionsreifen Beispielen, erklärt die Sicherheitsparameter und zeigt, welche CVEs in 2025/2026 zum sofortigen Update zwingen.

Voraussetzungen

Bevor du startest, stelle sicher, dass folgende Komponenten vorhanden sind:

KomponenteMindestversionEmpfohlenZweck
OpenSSL3.0.x3.5.5 LTSAlle Krypto-Operationen
Linux (Debian/Ubuntu)Ubuntu 22.04Ubuntu 24.04 LTSBetriebssystem
Bash/ZshBash 5.0Bash 5.2+Befehlsausführung
Root- oder sudo-ZugriffsudosudoPakete installieren
Python 3 (optional)3.103.12Zertifikat-Analyse-Skripte

Warum OpenSSL 3.5.5 LTS? Die Version schließt kritische Sicherheitslücken der Reihe 3.0 bis 3.4, darunter CVE-2025-15467 (High-Severity RCE in CMS AuthEnvelopedData-AEAD-Parsing). OpenSSL 1.1.1 erhielt seit September 2023 keine Sicherheits-Updates mehr und ist in Produktivumgebungen nicht mehr vertretbar. Systeme auf Ubuntu 20.04, die noch die vorinstallierte OpenSSL-1.1.1-Version nutzen, sollten auf Ubuntu 22.04 oder 24.04 migriert werden.

Schritt 1: OpenSSL installieren und Version prüfen

Unter Ubuntu/Debian ist OpenSSL 3.x seit Ubuntu 22.04 in den Standardrepositories enthalten. Auf älteren Systemen muss aus den Quellen kompiliert oder ein alternatives Repository genutzt werden.

# Paketquellen aktualisieren und OpenSSL installieren
sudo apt update && sudo apt install -y openssl

# Installierte Version prüfen
openssl version -a

# Erwartete Ausgabe (gekürzt):
# OpenSSL 3.5.5 8 Jun 2026 (Library: OpenSSL 3.5.5 8 Jun 2026)
# built on: reproducible build, date unspecified
# platform: linux-x86_64
# OPENSSLDIR: "/usr/lib/ssl"
# ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-3"

# Alle verfügbaren Digest-Algorithmen auflisten
openssl list -digest-algorithms | head -10

# Alle verfügbaren Cipher Suites auflisten
openssl list -cipher-algorithms | head -10

# TLS-1.3-Unterstützung prüfen
openssl s_client -connect google.com:443 -tls1_3 -brief 2>&1 | grep Protocol

Unter Windows lässt sich OpenSSL 3.5.x über den offiziellen Quell-Download oder über Chocolatey (choco install openssl) installieren. macOS-Nutzer greifen auf Homebrew zurück: brew install openssl@3.

Wichtiger Hinweis für macOS: Das Betriebssystem liefert unter /usr/bin/openssl noch LibreSSL aus, nicht OpenSSL. Nach brew install openssl@3 muss der Pfad angepasst werden: export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH". Andernfalls werden Homebrew-OpenSSL-Befehle von LibreSSL abgefangen, was zu unterschiedlichem Verhalten führen kann.

Schritt 2: RSA-Schlüsselpaar generieren

RSA ist der am weitesten verbreitete Algorithmus für asymmetrische Verschlüsselung und digitale Signaturen. Für neue Zertifikate empfiehlt das BSI (Technische Richtlinie TR-02102-2) mindestens 3.072 Bit für eine Sicherheit bis 2030 und 4.096 Bit darüber hinaus. RSA 2.048 Bit galt bis Ende 2025 als akzeptabel, sollte aber für neue Deployments nicht mehr verwendet werden.

Ab OpenSSL 3.x wird für die Schlüsselgenerierung der Befehl genpkey empfohlen, der direkt PKCS#8-Format ausgibt. Der ältere Befehl genrsa funktioniert weiterhin, gibt aber PKCS#1-Format aus, was bei manchen Anwendungen zu Kompatibilitätsproblemen führen kann.

# Moderner Weg: genpkey mit PKCS#8-Format (empfohlen ab OpenSSL 3.x)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out private-rsa.key

# Mit AES-256-CBC-Verschlüsselung schützen (Passphrase wird interaktiv abgefragt)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 \
  -aes-256-cbc -out private-rsa-encrypted.key

# Öffentlichen Schlüssel extrahieren
openssl pkey -in private-rsa.key -pubout -out public-rsa.key

# Schlüsselinformationen anzeigen
openssl pkey -in private-rsa.key -text -noout | head -5

# Erwartete Ausgabe:
# RSA Private-Key: (4096 bit, 2 primes)
# publicExponent: 65537 (0x10001)

# Alternativer Weg (PKCS#1-Format, ältere Syntax):
openssl genrsa -out private-pkcs1.key 4096

Die Schlüsselgenerierung mit 4.096 Bit dauert auf moderner Hardware weniger als eine Sekunde. Der öffentliche Exponent ist standardmäßig 65537 (0x10001), ein primzahlfreundlicher Wert, der schnelle Verschlüsselung und Signaturverifizierung ermöglicht. Die Details zu RSA-Verschlüsselung und wie sie in Node.js-Anwendungen eingebettet wird, erkläre ich im Artikel RSA-Verschlüsselung in Node.js: 11 Schritte [2026].

Schritt 3: ECDSA-Schlüsselpaar generieren (bevorzugter Ansatz)

Elliptic Curve Digital Signature Algorithm (ECDSA) mit der Kurve P-384 oder P-256 bietet bei deutlich kleineren Schlüsseln dieselbe Sicherheitsstärke wie RSA 7.680 Bit (P-384) bzw. RSA 3.072 Bit (P-256). TLS-1.3-Server und moderne Browser bevorzugen ECDSA gegenüber RSA, weil der Handshake schneller abläuft und die übertragenen Datenmengen geringer sind.

AlgorithmusSchlüssellängeSicherheitsstärkeSignatur-GrößeBSI-Empfehlung bis
RSA2.048 Bit112 Bit256 Byte2025
RSA3.072 Bit128 Bit384 Byte2030
RSA4.096 Bit140 Bit512 Byte2030+
ECDSA P-256256 Bit128 Bit64 Byte2030
ECDSA P-384384 Bit192 Bit96 Byte2030+
Ed25519256 Bit128 Bit64 Byte2030
ML-DSA-65 (Post-Quantum)1.952 Bit128 Bit (PQ-sicher)3.293 Bytenach 2030
# ECDSA P-384 Schlüssel generieren (BSI-empfohlen bis 2030+)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out private-ec-p384.key

# ECDSA P-256 Schlüssel generieren (maximale Kompatibilität)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out private-ec-p256.key

# Ed25519 Schlüssel generieren (schnellste Signierung, keine Kurven-Parameter)
openssl genpkey -algorithm Ed25519 -out private-ed25519.key

# Öffentlichen EC-Schlüssel extrahieren
openssl pkey -in private-ec-p384.key -pubout -out public-ec-p384.key

# EC-Schlüsselinformationen anzeigen
openssl pkey -in private-ec-p384.key -text -noout

# Erwartete Ausgabe:
# EC Key (id: 408)
# Public-Key: (384 bit)
# pub:
#     04:b4:e3:a7:...
# ASN1 OID: secp384r1
# NIST CURVE: P-384

Die Entscheidung zwischen P-256 und P-384 hängt vom Schutzbedarf ab. Für interne Dienste, die bis 2030 in Betrieb sind, reicht P-256. Für Zertifikate mit längerer Lebensdauer oder höherem Schutzbedarf empfiehlt die BSI Technische Richtlinie TR-02102 P-384. Die technischen Details zu elliptischer Kurven-Kryptografie erklärt der NIST FIPS 186-5 Standard.

Schritt 4: Selbstsigniertes Zertifikat erstellen

Selbstsignierte Zertifikate sind für Entwicklungsumgebungen, interne Dienste und Testaufbauten ideal. Browser und Clients vertrauen ihnen standardmäßig nicht, was bei öffentlichen Diensten ein Problem darstellt. Für öffentliche Server sollte stattdessen eine externe CA wie Let’s Encrypt genutzt werden. Für rein interne Infrastruktur bietet eine eigene CA (Schritt 6) die bessere Alternative zu einzelnen selbstsignierten Zertifikaten.

# Selbstsigniertes Zertifikat mit EC P-384 Schlüssel in einem Schritt
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-384 \
  -keyout self-signed.key \
  -out self-signed.crt \
  -days 365 \
  -noenc \
  -subj "/C=DE/ST=Bayern/L=Muenchen/O=MeinUnternehmen GmbH/CN=dev.example.com" \
  -addext "subjectAltName=DNS:dev.example.com,DNS:localhost,IP:127.0.0.1"

# Zertifikat vollständig anzeigen
openssl x509 -in self-signed.crt -text -noout

# Relevante Ausgabe-Auszüge:
# Certificate:
#   Data:
#     Version: 3 (0x2)
#     Serial Number: 7f:3a:b2:...
#     Signature Algorithm: ecdsa-with-SHA384
#     Issuer: C=DE, ST=Bayern, L=Muenchen, O=MeinUnternehmen GmbH, CN=dev.example.com
#     Validity
#         Not Before: Jun 17 09:00:00 2026 GMT
#         Not After : Jun 17 09:00:00 2027 GMT
#     Subject Alternative Name:
#         DNS:dev.example.com, DNS:localhost, IP Address:127.0.0.1

Kritischer Fallstrick: Seit 2017 lehnen alle gängigen Browser Zertifikate ohne Subject Alternative Names (SANs) ab, auch wenn der Common Name (CN) korrekt gesetzt ist. Der Parameter -addext "subjectAltName=..." ist deshalb Pflicht, nicht optional. Ohne SAN erscheint in Chrome und Firefox der Fehler NET::ERR_CERT_COMMON_NAME_INVALID. Das Zertifikat sieht in openssl-Ausgaben korrekt aus, wird aber vom Browser trotzdem abgelehnt.

Schritt 5: Certificate Signing Request (CSR) erstellen

Ein CSR (Certificate Signing Request) enthält den öffentlichen Schlüssel und die Identitätsinformationen, die an eine Certificate Authority (CA) gesendet werden. Die CA prüft die Angaben und stellt daraufhin ein signiertes Zertifikat aus. Für Let’s Encrypt oder kommerzielle CAs ist dieser Weg der Standard. Für die eigene interne CA (nächster Schritt) wird der CSR ebenfalls benötigt.

# Schritt 5a: Privaten Schlüssel generieren (falls noch nicht vorhanden)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out server.key

# Schritt 5b: CSR erstellen
openssl req -new \
  -key server.key \
  -out server.csr \
  -subj "/C=DE/ST=Bayern/L=Muenchen/O=MeinUnternehmen GmbH/OU=IT/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com"

# CSR-Inhalt prüfen
openssl req -in server.csr -text -noout | grep -A 5 "Subject"

# CSR-Signatur verifizieren (prüft die Integrität des CSR)
openssl req -in server.csr -verify -noout
# Erwartete Ausgabe: Certificate request self-signature verify OK

# CSR als Base64 anzeigen (für Übertragung an externe CA)
cat server.csr

Den fertigen CSR schickst du an deine gewünschte CA. Kommerzielle CAs wie DigiCert, Sectigo oder GlobalSign verlangen eine Domain-Validierung per E-Mail oder DNS-Record. Let’s Encrypt automatisiert diesen Prozess vollständig über das ACME-Protokoll. Für eine kostenlose Alternative mit automatischer Erneuerung erkläre ich den gesamten Prozess im Artikel Let’s Encrypt: Zertifikat in 12 Schritten einrichten [2026].

Schritt 6: Eigene Certificate Authority (CA) aufbauen

Eine eigene CA ist für interne Infrastruktur die beste Wahl: keine externen Abhängigkeiten, vollständige Kontrolle über Ausstellung und Widerruf, und Clients können das CA-Zertifikat einmalig importieren und vertrauen danach allen davon signierten Zertifikaten automatisch. Typische Einsatzfelder sind interne APIs, Kubernetes-Cluster, VPN-Dienste und Micro-Service-Architekturen.

Eine robuste CA-Infrastruktur besteht aus einer Root-CA (offline aufbewahrt) und mindestens einer Intermediate-CA (für die tägliche Zertifikatsausstellung). Für einfache Setups reicht eine einzelne CA ohne Intermediate-Ebene.

#!/bin/bash
# CA-Verzeichnisstruktur anlegen
mkdir -p myCA/{certs,crl,newcerts,private,csr}
chmod 700 myCA/private
touch myCA/index.txt
echo 1000 > myCA/serial
echo 1000 > myCA/crlnumber

# CA-Schlüssel generieren (stark verschlüsseln, offline aufbewahren!)
openssl genpkey -algorithm EC \
  -pkeyopt ec_paramgen_curve:P-384 \
  -aes-256-cbc \
  -pass pass:SICHERES_CA_PASSWORT \
  -out myCA/private/ca.key
chmod 400 myCA/private/ca.key

# CA-Zertifikat erstellen (20 Jahre Laufzeit für Root-CA)
openssl req -new -x509 \
  -key myCA/private/ca.key \
  -passin pass:SICHERES_CA_PASSWORT \
  -out myCA/certs/ca.crt \
  -days 7300 \
  -subj "/C=DE/ST=Bayern/O=MeinUnternehmen GmbH/CN=MeinUnternehmen Root CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:1" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -addext "subjectKeyIdentifier=hash"

# CA-Zertifikat prüfen
openssl x509 -in myCA/certs/ca.crt -text -noout | grep -E "(Issuer|Subject|Not|CA:)"

# Erwartete Ausgabe (Auszug):
# Issuer: C=DE, ST=Bayern, O=MeinUnternehmen GmbH, CN=MeinUnternehmen Root CA
# Not Before: Jun 17 09:00:00 2026 GMT
# Not After : Jun 14 09:00:00 2046 GMT
# CA:TRUE

Die Extension basicConstraints=critical,CA:TRUE kennzeichnet das Zertifikat als CA-Zertifikat. pathlen:1 erlaubt genau eine weitere CA-Ebene (Intermediate CA) darunter. Der Parameter keyUsage=critical,keyCertSign,cRLSign schränkt die Verwendung ausschließlich auf das Signieren von Zertifikaten und Widerrufslisten ein. Das critical-Flag erzwingt, dass Clients diese Extension verstehen und berücksichtigen müssen.

Schritt 7: Serverzertifikat mit eigener CA signieren

Mit der im vorherigen Schritt erstellten CA können nun Serverzertifikate für interne Dienste ausgestellt werden. Clients, die dem CA-Zertifikat vertrauen, akzeptieren alle davon signierten Zertifikate automatisch, ohne weitere Konfiguration.

# 1. Server-Schlüssel generieren
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out server.key

# 2. CSR erstellen
openssl req -new \
  -key server.key \
  -out server.csr \
  -subj "/C=DE/ST=Bayern/O=MeinUnternehmen GmbH/CN=api.intern.example.com"

# 3. Konfigurationsdatei für Extensions (WICHTIG für SAN und korrekte KeyUsage)
cat > server-ext.cnf << 'EOF'
[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
basicConstraints = CA:FALSE

[ alt_names ]
DNS.1 = api.intern.example.com
DNS.2 = *.intern.example.com
IP.1 = 192.168.1.100
EOF

# 4. Zertifikat mit CA signieren (365 Tage Laufzeit)
openssl x509 -req \
  -in server.csr \
  -CA myCA/certs/ca.crt \
  -CAkey myCA/private/ca.key \
  -passin pass:SICHERES_CA_PASSWORT \
  -CAcreateserial \
  -out server.crt \
  -days 365 \
  -extfile server-ext.cnf \
  -extensions v3_req

# 5. Zertifikatskette vollständig verifizieren
openssl verify -CAfile myCA/certs/ca.crt server.crt
# Erwartete Ausgabe: server.crt: OK

Empfehlung zur Laufzeit: Verwende für Serverzertifikate maximal 365 Tage. Apple hat seit September 2020 durchgesetzt, dass iOS und macOS keine Zertifikate mit mehr als 398 Tagen Laufzeit akzeptieren. Google Chrome plant, diesen Grenzwert bis 2027 schrittweise auf 90 Tage zu senken, was langfristig Automatisierung erzwingt.

Schritt 8: Zertifikate inspizieren und verifizieren

Das Inspizieren und Verifizieren von Zertifikaten ist eine der häufigsten OpenSSL-Aufgaben im Alltag. Diese Befehle helfen bei der Fehlersuche, der Ablaufüberwachung und dem Prüfen von Zertifikatsketten.

# Zertifikat vollständig anzeigen
openssl x509 -in server.crt -text -noout

# Nur spezifische Felder anzeigen
openssl x509 -in server.crt -noout -subject -issuer -dates -fingerprint

# Erwartete Ausgabe:
# subject=C=DE, ST=Bayern, O=MeinUnternehmen GmbH, CN=api.intern.example.com
# issuer=C=DE, ST=Bayern, O=MeinUnternehmen GmbH, CN=MeinUnternehmen Root CA
# notBefore=Jun 17 09:00:00 2026 GMT
# notAfter=Jun 17 09:00:00 2027 GMT
# SHA256 Fingerprint=A3:7F:2C:...

# Subject Alternative Names separat anzeigen
openssl x509 -in server.crt -noout -ext subjectAltName

# Privaten Schlüssel auf Übereinstimmung mit Zertifikat prüfen
# (beide md5-Hashes müssen identisch sein)
openssl x509 -noout -pubkey -in server.crt | openssl md5
openssl pkey -pubout -in server.key | openssl md5

# Zertifikat gegen CA mit spezifischem Zweck verifizieren
openssl verify -CAfile myCA/certs/ca.crt -purpose sslserver server.crt

# Ablaufdatum berechnen (Tage bis Ablauf)
NOT_AFTER=$(openssl x509 -noout -enddate -in server.crt | cut -d= -f2)
END_TS=$(date -d "$NOT_AFTER" +%s)
NOW_TS=$(date +%s)
echo "Zertifikat läuft ab in: $(( (END_TS - NOW_TS) / 86400 )) Tagen"

Die Prüfung mit -purpose sslserver verifiziert nicht nur die Zertifikatskette, sondern auch ob das Zertifikat tatsächlich für die Serverauthentifizierung geeignet ist. Fehlt die Extension extendedKeyUsage=serverAuth, schlägt diese Prüfung fehl, obwohl openssl verify ohne -purpose erfolgreich ist. Diese Unterscheidung ist bei der Fehlersuche wichtig.

Schritt 9: Live-TLS-Verbindung testen und analysieren

Mit openssl s_client lassen sich TLS-Verbindungen zu beliebigen Servern testen. Das Tool zeigt die Zertifikatskette, verwendete Cipher Suites, TLS-Protokollversion und Handshake-Details und ist damit ein unverzichtbares Diagnosewerkzeug.

# TLS-Verbindung zu einem öffentlichen Server testen
openssl s_client -connect example.com:443 -servername example.com -brief

# Nur TLS 1.3 erlauben (schlägt fehl, wenn Server kein TLS 1.3 unterstützt)
openssl s_client -connect example.com:443 -tls1_3 -brief

# Verbindung mit eigener CA verifizieren
openssl s_client -connect api.intern.example.com:443 \
  -CAfile myCA/certs/ca.crt \
  -servername api.intern.example.com

# Relevante Ausgabe-Auszüge:
# CONNECTED(00000003)
# depth=1 C=DE, ST=Bayern, O=MeinUnternehmen GmbH, CN=MeinUnternehmen Root CA
# verify return:1
# depth=0 CN=api.intern.example.com
# verify return:1
# ---
# SSL-Session:
#     Protocol  : TLSv1.3
#     Cipher    : TLS_AES_256_GCM_SHA384
# ---
# Verification: OK

# Zertifikat direkt vom Server herunterladen und prüfen
echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -subject -issuer -dates

# STARTTLS für E-Mail-Server (SMTP Port 587)
openssl s_client -connect mail.example.com:587 -starttls smtp

# STARTTLS für IMAP (Port 143)
openssl s_client -connect imap.example.com:143 -starttls imap

Der Subbefehl s_client funktioniert mit jedem TLS-fähigen Protokoll. Mit -starttls smtp bzw. -starttls imap lassen sich auch E-Mail-Server prüfen. Das ist besonders nützlich, um zu verifizieren, dass ein frisch ausgestelltes Zertifikat korrekt konfiguriert ist und die vollständige Zertifikatskette mitgesendet wird. Grundlagen zu TLS 1.3 und dem Handshake-Prozess findest du in HTTPS und TLS erklärt: Was der Schloss-Button wirklich bedeutet.

Schritt 10: Wildcard- und Multi-Domain-Zertifikate

Wildcard-Zertifikate (z.B. *.example.com) decken alle Subdomains einer Ebene ab. Sie sind praktisch für interne Infrastruktur, setzen aber bei öffentlichen CAs eine DNS-basierte Validierung voraus. Mit der eigenen CA sind sie problemlos möglich. Ein häufiges Missverständnis: ein Wildcard deckt nur eine Subdomain-Ebene ab.

# Konfigurationsdatei für Wildcard + Multi-Domain-Zertifikat
cat > wildcard-ext.cnf << 'EOF'
[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
basicConstraints = CA:FALSE

[ alt_names ]
DNS.1 = example.com
DNS.2 = *.example.com
DNS.3 = *.api.example.com
DNS.4 = intern.example.com
IP.1 = 10.0.0.1
IP.2 = 172.16.0.1
EOF

# Wildcard-Schlüssel und CSR generieren
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out wildcard.key
openssl req -new -key wildcard.key -out wildcard.csr \
  -subj "/C=DE/ST=Bayern/O=MeinUnternehmen GmbH/CN=*.example.com"

# Mit CA signieren (max. 365 Tage)
openssl x509 -req -in wildcard.csr \
  -CA myCA/certs/ca.crt \
  -CAkey myCA/private/ca.key \
  -passin pass:SICHERES_CA_PASSWORT \
  -CAcreateserial \
  -out wildcard.crt \
  -days 365 \
  -extfile wildcard-ext.cnf \
  -extensions v3_req

# SAN-Einträge des ausgestellten Zertifikats prüfen
openssl x509 -in wildcard.crt -noout -ext subjectAltName
# Ausgabe:
# X509v3 Subject Alternative Name:
#     DNS:example.com, DNS:*.example.com, DNS:*.api.example.com,
#     DNS:intern.example.com, IP Address:10.0.0.1, IP Address:172.16.0.1

Einschränkungen von Wildcards: Das Muster *.example.com deckt api.example.com ab, aber nicht dev.api.example.com (zwei Ebenen tiefer). Für mehrere Ebenen werden separate Wildcard-Einträge wie *.api.example.com benötigt. Außerdem deckt der Wildcard nicht die Apex-Domain example.com selbst ab, weshalb sie als separater DNS.1-Eintrag aufgenommen werden muss.

Schritt 11: Zertifikatsformate konvertieren (PEM, DER, PKCS#12)

In der Praxis existieren verschiedene Zertifikatsformate, die von unterschiedlichen Systemen erwartet werden. Java-Keystores benötigen PKCS#12 (.p12/.pfx), Windows-Systeme oft DER (.der/.cer), und Linux-Server arbeiten mit PEM (.pem/.crt).

FormatDateiendungEncodingVerwendungEnthält
PEM.pem, .crt, .keyBase64 (ASCII)Linux, Apache, NginxZertifikat, Schlüssel oder beides
DER.der, .cerBinär (ASN.1)Windows, Java, iOSNur Zertifikat
PKCS#12.pfx, .p12Binär, verschlüsseltWindows, Java, Android, macOSZertifikat + Schlüssel + Chain
PKCS#7.p7b, .p7cBase64 oder BinärWindows, JavaNur Zertifikate (kein Schlüssel)
# PEM zu DER konvertieren
openssl x509 -in server.crt -outform DER -out server.der

# DER zu PEM konvertieren
openssl x509 -in server.der -inform DER -out server-from-der.crt

# PEM zu PKCS#12 (mit Schlüssel und CA-Zertifikat)
openssl pkcs12 -export \
  -in server.crt \
  -inkey server.key \
  -certfile myCA/certs/ca.crt \
  -out server.p12 \
  -name "api.intern.example.com" \
  -passout pass:PKCS12_PASSWORT

# PKCS#12 zu PEM (alle Bestandteile)
openssl pkcs12 -in server.p12 -passin pass:PKCS12_PASSWORT \
  -out server-extracted.pem -nodes

# Ältere .pfx-Dateien mit Legacy-Algorithmen öffnen (OpenSSL 3.x)
openssl pkcs12 -legacy -in old-windows.pfx -passin pass:PKCS12_PASSWORT \
  -out extracted-legacy.pem -nodes

# Zertifikatskette (fullchain) für Nginx/Apache erstellen
cat server.crt myCA/certs/ca.crt > fullchain.crt

Schritt 12: Sicherheit, Best Practices und Schlüsselverwaltung

Die kryptografische Stärke von OpenSSL hängt nicht nur von den Algorithmen ab, sondern auch von der Sorgfalt bei Konfiguration, Schlüsselspeicherung und Update-Disziplin. Diese letzten Maßnahmen entscheiden über die langfristige Sicherheit der gesamten PKI-Infrastruktur.

# Korrekte Dateiberechtigungen setzen (unverzichtbar)
chmod 600 server.key private-ec-p384.key
chmod 400 myCA/private/ca.key  # CA-Schlüssel: nur lesen, kein Schreiben
sudo chown root:root myCA/private/ca.key

# Berechtigungen überprüfen
ls -la server.key myCA/private/ca.key
# Korrekte Ausgabe:
# -rw------- 1 user  user  241 Jun 17 09:00 server.key
# -r-------- 1 root  root  313 Jun 17 09:00 myCA/private/ca.key

# System-weit sichere TLS-Standards erzwingen (openssl.cnf)
# Pfad prüfen:
openssl version -d  # zeigt OPENSSLDIR

# Empfohlene Einstellungen in /usr/lib/ssl/openssl.cnf:
# [system_default_sect]
# MinProtocol = TLSv1.2
# CipherString = DEFAULT@SECLEVEL=2
# Curves = P-384:P-256:X25519

# Passphrase eines Schlüssels entfernen (für automatische Dienste)
openssl pkey -in encrypted.key -passin pass:PASSWORT -out unencrypted.key
chmod 600 unencrypted.key

# CA-Zertifikat systemweit als vertrauenswürdig eintragen (Ubuntu/Debian)
sudo cp myCA/certs/ca.crt /usr/local/share/ca-certificates/mein-intern-ca.crt
sudo update-ca-certificates
# Ausgabe: 1 added, 0 removed; done.

# Test: Curl mit eigener CA ohne explizites --cacert
curl https://api.intern.example.com/health

Für hochsicherheitskritische Umgebungen sollte der CA-Schlüssel auf einem Hardware Security Module (HSM) gespeichert werden. Günstige Alternativen für kleinere Setups sind YubiKeys (mit OpenPGP- oder PIV-Modul) oder Nitrokeys. OpenSSL unterstützt den Zugriff auf PKCS#11-fähige HSMs über das Engine-Interface (engine pkcs11 in OpenSSL 3.x).

Häufige Fallstricke mit OpenSSL-Zertifikaten

Fallstrick 1: Fehlende Subject Alternative Names (SAN)

Seit Chrome 58 (2017) und gemäß RFC 2818 ignorieren Browser den Common Name (CN) für die Hostnamen-Validierung vollständig. Nur SANs werden geprüft. Symptom in Chrome: NET::ERR_CERT_COMMON_NAME_INVALID, in Firefox: SSL_ERROR_BAD_CERT_DOMAIN. Das Zertifikat sieht in openssl-Ausgaben korrekt aus, was die Diagnose erschwert. Lösung: Immer -addext "subjectAltName=DNS:example.com" verwenden und mit openssl x509 -in cert.crt -noout -ext subjectAltName verifizieren.

Fallstrick 2: Veraltete OpenSSL-Version im Einsatz

OpenSSL 1.1.1 erhält seit September 2023 keine Sicherheits-Updates mehr, ist jedoch noch auf vielen Ubuntu-20.04-Systemen vorinstalliert. Diese Version ist anfällig für alle seit 2023 entdeckten CVEs. Abhilfe: System auf Ubuntu 22.04 oder 24.04 aktualisieren oder OpenSSL 3.x manuell installieren. Prüfung: openssl version. Sollte mit "3.x.x" beginnen.

Fallstrick 3: Privater Schlüssel passt nicht zum Zertifikat

Nginx und Apache starten nicht, wenn Schlüssel und Zertifikat nicht zusammenpassen. Fehlermeldung: SSL_CTX_use_PrivateKey_file failed oder Private key does not match the certificate public key. Diagnose: Die öffentlichen Schlüssel-Hashes müssen identisch sein.

# Öffentliche Schlüssel beider Dateien vergleichen
openssl x509 -noout -pubkey -in server.crt | openssl md5
openssl pkey -pubout -in server.key | openssl md5
# Identische Ausgabe zeigt korrekte Paarung an

Fallstrick 4: Zu lange Zertifikatslaufzeit

Apple erzwingt seit September 2020 eine maximale Zertifikatslaufzeit von 398 Tagen. Zertifikate mit längerer Laufzeit werden auf iOS, macOS und Safari abgelehnt, auch wenn sie von einer gültigen CA signiert wurden. Verwende maximal -days 365 für Serverzertifikate. Für Root-CAs sind 20 Jahre (7.300 Tage) akzeptabel, da sie offline aufbewahrt und nicht in Handshakes ausgetauscht werden.

Fallstrick 5: CA-Zertifikat nicht als vertrauenswürdig eingetragen

Selbst wenn das Zertifikat korrekt von der eigenen CA signiert ist, erscheint im Browser NET::ERR_CERT_AUTHORITY_INVALID, solange das CA-Zertifikat nicht im Trust Store des Clients eingetragen ist. Jedes Gerät und jeder Browser muss das CA-Zertifikat einmalig importieren. Für Unternehmensumgebungen automatisiert Group Policy Object (GPO) unter Windows bzw. MDM-Profile unter macOS/iOS diesen Prozess.

Fallstrick 6: Passphrase-geschützte Schlüssel blockieren Dienst-Neustarts

Nginx und Apache können beim Start nach einer Passphrase fragen. Das verhindert automatische Neustarts nach System-Updates und sorgt für Ausfallzeiten. Für Produktivserver sollte der Schlüssel entweder passphrasenlos sein (mit 600er Dateiberechtigungen) oder ein Secrets-Manager wie HashiCorp Vault die Passphrase automatisch bereitstellen. Passphrase entfernen: openssl pkey -in encrypted.key -passin pass:PASSWORT -out unencrypted.key.

Fallstrick 7: Fehlende oder falsche basicConstraints-Extension

Ohne die Extension basicConstraints=CA:FALSE in Serverzertifikaten könnten diese theoretisch als CA missbraucht werden. Moderne Browser prüfen dies und lehnen Zertifikate ohne korrekte basicConstraints ab. CA-Zertifikate benötigen zwingend CA:TRUE und keyUsage=keyCertSign. Prüfung: openssl x509 -in cert.crt -noout -text | grep -A 3 "Basic Constraints".

Troubleshooting: 10 häufige OpenSSL-Fehlermeldungen

FehlermeldungUrsacheLösung
unable to load certificateDatei nicht gefunden oder falsches FormatPfad prüfen; -inform DER bei Binärdateien angeben
no certificate file foundLeere PEM-Datei oder falscher MIME-Typhead -1 cert.crt: muss -----BEGIN CERTIFICATE----- enthalten
certificate signature failureCA-Schlüssel passt nicht zum CA-ZertifikatCA-Schlüsselpaar neu generieren oder korrektes CA.key verwenden
unable to get local issuer certificateIntermediate-CA-Zertifikat fehlt in der ChainFullchain erstellen: cat cert.crt intermediate.crt ca.crt > fullchain.crt
CERTIFICATE_VERIFY_FAILEDCA nicht im Trust Store oder Zertifikat abgelaufenCA-Zertifikat importieren oder neues Zertifikat ausstellen
no shared cipherKeine gemeinsamen Cipher Suites zwischen Client und ServerMinimale TLS-Version und Cipher Suites auf beiden Seiten angleichen
PKCS12 MAC could not be verifiedFalsches Passwort oder Legacy-AlgorithmusKorrektes Passwort; -legacy Flag für alte .pfx-Dateien
routines::wrong tagDER-Datei wird als PEM geladen-inform DER explizit angeben
Error, extension value length mismatchSyntaxfehler in der .cnf-KonfigurationsdateiKonfigurationsdatei Zeile für Zeile prüfen; besonders Leerzeichen und Kommas
Private key does not match the certificate public keyFalsche Schlüsseldatei angegebenÖffentliche Schlüssel beider Dateien mit openssl md5 vergleichen

Vollständiges Beispielprojekt: Interne Microservice-PKI

Das folgende Shell-Skript richtet eine vollständige interne PKI für eine Microservice-Umgebung ein: Root-CA, Intermediate-CA und drei Serverzertifikate. Das Two-Tier-Modell ist Best Practice: Der Root-CA-Schlüssel bleibt offline und wird nur zum Signieren der Intermediate-CA genutzt. Bei Kompromittierung der Intermediate-CA kann ohne Neuerstellung der Root-CA eine neue Intermediate ausgestellt werden.

#!/bin/bash
# Vollständiges PKI-Setup für Microservice-Umgebung
# Getestet mit OpenSSL 3.5.5 LTS auf Ubuntu 24.04

set -euo pipefail

CA_PASS="SICHERES_PASSWORT_HIER_ERSETZEN"
PKI_DIR="./pki"
SERVICES=("api-gateway" "postgres-db" "grafana")
DOMAINS=("api.intern" "db.intern" "metrics.intern")

echo "[1/6] Verzeichnisstruktur anlegen..."
mkdir -p "$PKI_DIR"/{root-ca/{certs,private,csr},intermediate/{certs,private,csr},server}
chmod 700 "$PKI_DIR"/root-ca/private "$PKI_DIR"/intermediate/private
touch "$PKI_DIR"/root-ca/index.txt "$PKI_DIR"/intermediate/index.txt
echo 1000 > "$PKI_DIR"/root-ca/serial
echo 2000 > "$PKI_DIR"/intermediate/serial

echo "[2/6] Root-CA erstellen (offline aufbewahren)..."
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 \
  -aes-256-cbc -pass pass:"$CA_PASS" \
  -out "$PKI_DIR/root-ca/private/root.key"
openssl req -new -x509 -key "$PKI_DIR/root-ca/private/root.key" \
  -passin pass:"$CA_PASS" -out "$PKI_DIR/root-ca/certs/root.crt" -days 7300 \
  -subj "/C=DE/O=MeinUnternehmen/CN=Root CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:1" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

echo "[3/6] Intermediate-CA erstellen..."
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 \
  -aes-256-cbc -pass pass:"$CA_PASS" \
  -out "$PKI_DIR/intermediate/private/inter.key"
openssl req -new -key "$PKI_DIR/intermediate/private/inter.key" \
  -passin pass:"$CA_PASS" -out "$PKI_DIR/intermediate/csr/inter.csr" \
  -subj "/C=DE/O=MeinUnternehmen/CN=Intermediate CA"
openssl x509 -req -in "$PKI_DIR/intermediate/csr/inter.csr" \
  -CA "$PKI_DIR/root-ca/certs/root.crt" \
  -CAkey "$PKI_DIR/root-ca/private/root.key" -passin pass:"$CA_PASS" \
  -CAcreateserial -out "$PKI_DIR/intermediate/certs/inter.crt" -days 1825 \
  -extfile <(printf "[v3]\nbasicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign") \
  -extensions v3

echo "[4/6] Serverzertifikate fuer alle Services erstellen..."
for i in "${!SERVICES[@]}"; do
  SVC="${SERVICES[$i]}"
  DOM="${DOMAINS[$i]}"
  openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 \
    -out "$PKI_DIR/server/$SVC.key"
  openssl req -new -key "$PKI_DIR/server/$SVC.key" \
    -out "$PKI_DIR/server/$SVC.csr" \
    -subj "/C=DE/O=MeinUnternehmen/CN=$DOM"
  openssl x509 -req -in "$PKI_DIR/server/$SVC.csr" \
    -CA "$PKI_DIR/intermediate/certs/inter.crt" \
    -CAkey "$PKI_DIR/intermediate/private/inter.key" -passin pass:"$CA_PASS" \
    -CAcreateserial -out "$PKI_DIR/server/$SVC.crt" -days 365 \
    -extfile <(printf "[v3]\nsubjectAltName=DNS:%s,DNS:%s\nbasicConstraints=CA:FALSE\nkeyUsage=critical,digitalSignature\nextendedKeyUsage=serverAuth" "$DOM" "$SVC") \
    -extensions v3
  echo "  OK: $SVC ($DOM)"
done

echo "[5/6] Vollstaendige Zertifikatskette erstellen..."
cat "$PKI_DIR/intermediate/certs/inter.crt" \
    "$PKI_DIR/root-ca/certs/root.crt" > "$PKI_DIR/fullchain-ca.crt"

echo "[6/6] Alle Serverzertifikate verifizieren..."
for SVC in "${SERVICES[@]}"; do
  openssl verify -CAfile "$PKI_DIR/fullchain-ca.crt" "$PKI_DIR/server/$SVC.crt"
done

echo ""
echo "PKI-Setup abgeschlossen!"
echo "CA-Zertifikat fuer Trust-Store-Import: $PKI_DIR/root-ca/certs/root.crt"
echo "Root-CA-Schluessel JETZT offline sichern: $PKI_DIR/root-ca/private/root.key"

OpenSSL-Sicherheitslücken 2025/2026: Kritische CVEs im Überblick

OpenSSL war in den letzten 12 Monaten Ziel mehrerer schwerwiegender Sicherheitslücken. Die vollständige CVE-Liste wird unter openssl.org/news/vulnerabilities.html gepflegt.

CVESchweregradBetroffene VersionenTypFix
CVE-2025-15467High (RCE)3.0 bis 3.6Stack-Buffer-Overflow in CMS AuthEnvelopedData, pre-auth3.5.5+
CVE-2025-11187Moderate3.4, 3.5, 3.6Stack-Buffer-Overflow in PKCS#12 MAC-Verifizierung3.5.5+
CVE-2025-15468High3.x mit QUICNULL-Pointer-Dereferenz im QUIC-Handler (DoS)3.5.5+
CVE-2025-66199High3.xÜbermäßige Speicherzuweisung in TLS-1.3-Zertifikatskomprimierung (DoS)3.5.5+
CVE-2026-42766Highvor 3.5NULL-Dereferenz in CMS-Entschlüsselung3.5+
CVE-2026-45446Highvor 3.5Falsches Tag-Processing in AES-GCM-SIV für leere Nachrichten3.5+

CVE-2025-15467 ist besonders kritisch: Es handelt sich um einen pre-auth ausnutzbaren RCE-Fehler in der AEAD-Parsing-Logik. Alle Systeme mit OpenSSL 3.0 bis 3.6 sind betroffen und sollten sofort auf 3.5.5 aktualisiert werden. Das Update ist über den Paketmanager verfügbar: sudo apt update && sudo apt upgrade openssl. Nach dem Update den Dienst neu starten, der OpenSSL nutzt.

Post-Quantum-Kryptografie: OpenSSL 3.5+ unterstützt ML-KEM (CRYSTALS-Kyber, für Schlüsselaustausch) und ML-DSA (CRYSTALS-Dilithium, für Signaturen) als experimentelle Algorithmen. Sie ersetzen langfristig RSA und ECDSA gegen Quantencomputer-Angriffe. Mehr dazu in ML-KEM (Kyber) in Node.js: Post-Quantum-Kryptografie in 12 Schritten [2026] und Post-Quantum-Kryptografie: 50% des Webs jetzt sicher [2026].

Die technische Spezifikation für TLS 1.3, den Protokollstandard hinter HTTPS, ist als RFC 8446 bei der IETF frei zugänglich. Die vollständige Dokumentation aller OpenSSL-3.5-Befehle findet sich in der offiziellen OpenSSL-3.5-Manpage.

Fortgeschrittene Themen: OCSP, CRL und Zertifikatswiderruf

Für produktive PKI-Infrastrukturen reicht es nicht, Zertifikate nur auszustellen. Kompromittierte oder fehlerhaft ausgestellte Zertifikate müssen widerrufbar sein, bevor sie ablaufen. Dafür gibt es zwei Mechanismen: Certificate Revocation Lists (CRL) und Online Certificate Status Protocol (OCSP). Beide sind komplementär, haben aber unterschiedliche Eigenschaften.

CRL (Certificate Revocation List): Eine CRL ist eine regelmäßig aktualisierte, von der CA signierte Liste von Seriennummern widerrufener Zertifikate. Clients laden die CRL periodisch herunter und prüfen lokal, ob ein Zertifikat widerrufen ist. Nachteil: Die CRL kann groß werden und ist nur so aktuell wie die letzte Distribution.

OCSP (Online Certificate Status Protocol): OCSP ermöglicht eine Echtzeit-Abfrage des Zertifikatsstatus direkt beim OCSP-Responder der CA. Clients senden die Seriennummer und erhalten eine signierte Antwort ("good", "revoked" oder "unknown"). OCSP-Stapling ist eine Optimierung: Der Webserver fragt selbst den OCSP-Status ab und sendet die signierte Antwort im TLS-Handshake mit, was Client-Anfragen an den OCSP-Responder eliminiert.

# Schritt 1: CRL-Seriennummer initialisieren
echo 1000 > myCA/crlnumber

# Schritt 2: Leere initiale CRL erstellen
# (openssl.cnf muss [CA_default] mit dir, database, serial, crlnumber konfiguriert haben)
openssl ca -gencrl \
  -keyfile myCA/private/ca.key \
  -cert myCA/certs/ca.crt \
  -passin pass:SICHERES_CA_PASSWORT \
  -out myCA/crl/ca.crl \
  -crldays 30

# CRL-Inhalt anzeigen
openssl crl -in myCA/crl/ca.crl -text -noout

# Schritt 3: Zertifikat widerrufen
openssl ca -revoke server.crt \
  -keyfile myCA/private/ca.key \
  -cert myCA/certs/ca.crt \
  -passin pass:SICHERES_CA_PASSWORT \
  -reason keyCompromise

# Schritt 4: CRL nach Widerruf aktualisieren
openssl ca -gencrl -keyfile myCA/private/ca.key \
  -cert myCA/certs/ca.crt -passin pass:SICHERES_CA_PASSWORT \
  -out myCA/crl/ca.crl -crldays 30

# OCSP-Abfrage gegen externen Server (z.B. Let's Encrypt)
echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -ocsp_uri
# Gibt die OCSP-Responder-URL des Zertifikats aus

# OCSP-Status direkt abfragen
OCSP_URL=$(echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -ocsp_uri)
echo | openssl s_client -connect example.com:443 2>/dev/null > /tmp/cert.pem
openssl ocsp -issuer /etc/ssl/certs/ISRG_Root_X1.pem \
  -cert /tmp/cert.pem -url "$OCSP_URL" -resp_text -noverify 2>/dev/null | head -5

Für Nginx lässt sich OCSP-Stapling mit zwei Direktiven aktivieren: ssl_stapling on; und ssl_stapling_verify on;. Nginx fragt dann im Hintergrund den OCSP-Responder ab und sendet die gecachte Antwort im Handshake mit. Das reduziert die Latenz für Clients und schützt deren Privatsphäre, weil keine OCSP-Anfragen an externe Server nötig sind.

OpenSSL in Automatisierungs-Pipelines: Monitoring und Zertifikatsablauf

Abgelaufene Zertifikate sind einer der häufigsten Gründe für ungeplante Ausfälle. In einer Infrastruktur mit mehreren Zertifikaten ist manuelles Monitoring schnell fehleranfällig. Das folgende Skript prüft alle Zertifikate in einem Verzeichnis auf ihr Ablaufdatum und gibt eine Warnung bei weniger als 30 Tagen aus.

#!/bin/bash
# Zertifikats-Ablauf-Monitor für alle .crt-Dateien im angegebenen Verzeichnis
# Verwendung: ./cert-monitor.sh /etc/ssl/certs /path/to/server-certs

WARN_DAYS=30
EXIT_CODE=0

for CERT_DIR in "$@"; do
  echo "=== Prüfe Zertifikate in $CERT_DIR ==="
  for CERT in "$CERT_DIR"/*.crt "$CERT_DIR"/*.pem; do
    [ -f "$CERT" ] || continue
    NOT_AFTER=$(openssl x509 -noout -enddate -in "$CERT" 2>/dev/null | cut -d= -f2)
    [ -z "$NOT_AFTER" ] && continue
    END_TS=$(date -d "$NOT_AFTER" +%s 2>/dev/null) || continue
    NOW_TS=$(date +%s)
    DAYS_LEFT=$(( (END_TS - NOW_TS) / 86400 ))
    SUBJECT=$(openssl x509 -noout -subject -in "$CERT" 2>/dev/null | sed 's/subject=//')

    if [ "$DAYS_LEFT" -le 0 ]; then
      echo "KRITISCH: $CERT ($SUBJECT) ist abgelaufen!"
      EXIT_CODE=2
    elif [ "$DAYS_LEFT" -le "$WARN_DAYS" ]; then
      echo "WARNUNG: $CERT ($SUBJECT) läuft in $DAYS_LEFT Tagen ab"
      EXIT_CODE=1
    else
      echo "OK: $CERT ($SUBJECT) - noch $DAYS_LEFT Tage"
    fi
  done
done

exit $EXIT_CODE

Dieses Skript lässt sich direkt als Nagios/Icinga-Check, als Cron-Job mit E-Mail-Alert oder als Prometheus-Exporter (über textfile collector) einsetzen. Für größere Infrastrukturen empfehlen sich spezialisierte Tools wie certbot renew --dry-run für Let's Encrypt, Vault PKI Secrets Engine von HashiCorp oder cert-manager für Kubernetes.

Eine weitere wichtige Automatisierung ist die automatische Zertifikatserneuerung. Für interne CAs lässt sich ein Cron-Job einrichten, der 30 Tage vor Ablauf ein neues Zertifikat ausstellt, den Dienst neu konfiguriert und bei Nginx/Apache einen sanften Reload auslöst (nginx -s reload). Das ganze Ecosystem von ACME-Protokoll und automatischer Erneuerung wird im Artikel Nginx Reverse Proxy: HTTPS in 12 Schritten konfigurieren [2026] am Produktionsbeispiel gezeigt.

OpenSSL als Krypto-Labor: Hashing, Verschlüsselung und Signaturen

Neben Zertifikaten bietet OpenSSL auch direkte Krypto-Funktionen für den Einsatz in Skripten und Pipelines: symmetrische Verschlüsselung, Hash-Berechnung und digitale Signaturen. Diese Befehle sind nützlich für Datei-Verschlüsselung, Integritätsprüfungen und schnelle Tests.

# Datei mit AES-256-CBC verschlüsseln (passwortbasiert)
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 \
  -in geheime-daten.txt -out geheime-daten.enc \
  -pass pass:SICHERES_PASSWORT

# Verschlüsselte Datei entschlüsseln
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -d \
  -in geheime-daten.enc -out geheime-daten-entschlüsselt.txt \
  -pass pass:SICHERES_PASSWORT

# SHA-256 Hash einer Datei berechnen
openssl dgst -sha256 datei.iso
# Ausgabe: SHA2-256(datei.iso)= a3f7b2...

# HMAC-SHA256 mit Schlüssel berechnen
echo -n "Nachrichteninhalt" | openssl dgst -sha256 -hmac "GEHEIMER_SCHLUESSEL"

# Datei mit privatem Schlüssel signieren (ECDSA)
openssl dgst -sha384 -sign private-ec-p384.key \
  -out datei.sig datei.txt

# Signatur mit öffentlichem Schlüssel verifizieren
openssl dgst -sha384 -verify public-ec-p384.key \
  -signature datei.sig datei.txt
# Ausgabe bei Erfolg: Verified OK

# Zufällige Bytes generieren (für Schlüssel, Tokens, Salts)
openssl rand -hex 32   # 32 Byte = 64 Hex-Zeichen (256-Bit-Token)
openssl rand -base64 32  # 32 Byte als Base64 (für Passwörter/Secrets)

Der Befehl openssl rand -hex 32 ist eine schnelle Möglichkeit, kryptografisch sichere Zufallswerte zu generieren, z.B. für API-Tokens, Session-Secrets oder Datenbankpasswörter. Die zugrundeliegende Entropiequelle ist das Betriebssystem (/dev/urandom auf Linux), das durch Kernel-interne Hardware-Entropie (CPU-Rauschen, Mausbewegungen) gespeist wird.

Details zu HMAC-SHA256 und dessen Implementierung in Node.js-Anwendungen für API-Authentifizierung findest du im Artikel HMAC-SHA256 in Node.js: 10 Schritte [2026]. Für AES-256-Verschlüsselung in JavaScript-Anwendungen empfehle ich AES-256-Verschlüsselung in Node.js: 12 Schritte [2026].

Weiterführende Ressourcen

Verwandte Artikel auf shattered.io

FAQ: OpenSSL-Zertifikate und Schlüssel

Was ist der Unterschied zwischen OpenSSL 3.5 LTS und 4.0.0?

OpenSSL 3.5.5 ist die Long-Term-Support-Version mit Support bis April 2030. Sie ist für Produktivumgebungen empfohlen und enthält keine inkompatiblen API-Änderungen gegenüber 3.4. OpenSSL 4.0.0 (veröffentlicht April 2026) bringt inkompatible Änderungen, entfernt alle veralteten Low-Level-Funktionen und fügt Post-Quantum-Algorithmen (ML-KEM, ML-DSA) als vollständig unterstützte Features hinzu. Version 4.0.0 eignet sich für neue Projekte mit explizitem PQC-Bedarf, setzt aber aufwändige Migrationstests voraus, da veraltete API-Aufrufe zu Kompilierungsfehlern führen.

Wie lange sollten verschiedene Zertifikatstypen gültig sein?

Root-CA-Zertifikate: 20 Jahre (7.300 Tage), da sie offline aufbewahrt werden und nicht in TLS-Handshakes erscheinen. Intermediate-CA-Zertifikate: 5 Jahre (1.825 Tage). Serverzertifikate: maximal 365 Tage (398 Tage ist das technische Maximum durch Apple). Ab 2027 plant Google Chrome, die maximale Laufzeit für öffentlich vertrauenswürdige Zertifikate auf 90 Tage zu reduzieren, was Automatisierung wie Let's Encrypt certbot unumgänglich macht.

ECDSA P-256 oder RSA 4096 für neue Serverzertifikate?

ECDSA P-384 (oder P-256 für maximale Kompatibilität) ist die bessere Wahl für neue Deployments. Die Gründe: kleinere Schlüssel und Signaturen (96 Byte bei P-384 vs. 512 Byte bei RSA 4096), schnellerer TLS-Handshake, bessere Performance auf Mobilgeräten und volle TLS-1.3-Kompatibilität. RSA 4096 ist nur sinnvoll, wenn Legacy-Clients ohne EC-Unterstützung bedient werden müssen, was heutzutage selten vorkommt.

Was ist der Unterschied zwischen PEM und DER?

PEM (Privacy Enhanced Mail) ist Base64-kodiertes DER mit Header- und Footer-Zeilen (-----BEGIN CERTIFICATE----- / -----END CERTIFICATE-----). DER ist das binäre ASN.1-Encoding. PEM ist das Format der Wahl auf Linux/Unix-Systemen, da es lesbar und in Textdateien einbettbar ist. DER wird von Java-Keystores, Windows CryptoAPI und älteren Systemen erwartet. OpenSSL konvertiert zwischen beiden mit -inform/-outform DER/PEM.

Was tun bei "PKCS12 MAC could not be verified"?

Diese Fehlermeldung tritt auf, wenn das Passwort falsch ist oder wenn eine ältere .pfx-Datei mit veralteten Legacy-Algorithmen (RC2-40-CBC für den MAC) vorliegt. In OpenSSL 3.x müssen Legacy-Dateien mit dem Flag -legacy geöffnet werden: openssl pkcs12 -legacy -in old-file.pfx -passin pass:PASSWORT -out extracted.pem -nodes. Die Legacy-Algorithmen sind in OpenSSL 3.x standardmäßig deaktiviert, weil sie als schwach eingestuft sind.

Wie prüfe ich, ob ein Server TLS 1.3 unterstützt?

Mit dem Befehl openssl s_client -connect server.example.com:443 -tls1_3 -brief 2>&1 | grep Protocol. Gibt die Verbindung Protocol: TLSv1.3 zurück, unterstützt der Server TLS 1.3. Schlägt sie mit no protocols available oder ssl handshake failure fehl, ist TLS 1.3 nicht aktiviert oder der Server nutzt eine veraltete OpenSSL-Version (vor 1.1.1). Nginx aktiviert TLS 1.3 über ssl_protocols TLSv1.2 TLSv1.3; in der Konfiguration.

Können selbstsignierte Zertifikate sicher sein?

Kryptografisch sind selbstsignierte Zertifikate genauso stark wie CA-signierte. Das Problem ist das Vertrauensmodell: Browser vertrauen nur Zertifikaten von CAs in ihrem Trust Store. Ein selbstsigniertes Zertifikat kann von jedem erstellt werden und bietet deshalb keine Identitätsgarantie ohne manuellen Trust-Store-Eintrag. Für interne Dienste, bei denen du das CA-Zertifikat selbst an alle Clients verteilst, sind sie vollständig geeignet. Für öffentliche Dienste ist Let's Encrypt die bessere Wahl, da kein manueller Trust-Eintrag nötig ist.

Was ist der Unterschied zwischen openssl req und openssl x509?

openssl req verarbeitet PKCS#10 Certificate Signing Requests (CSRs) und kann damit sowohl CSRs erstellen als auch selbstsignierte Zertifikate ausstellen. openssl x509 verarbeitet fertige X.509-Zertifikate, zeigt ihren Inhalt an, konvertiert Formate und kann CSRs signieren (als vereinfachter CA-Befehl ohne die volle Infrastruktur von openssl ca). Für die meisten Anwendungsfälle ist openssl x509 -req zum Signieren ausreichend. Der komplexere Befehl openssl ca bietet zusätzlich automatische Seriennummern-Verwaltung, Datenbankführung und CRL-Support.