feat(cert-manager): Reiter „Dateien“ mit mehreren Dateien und ein Parser für RSA und EC – Durchstich

- Ein gemeinsamer Arbeitsbereich im Browser: jede Auswahl hängt an, eine zweite Datei ersetzt nie die erste
- Ein Parser (node:crypto) für RSA- und EC-Zertifikate als PEM, DER und TRUSTED CERTIFICATE, Rolle je Datei
- Neue Route analyze (mehrere Dateien, 30 x 5 MiB, zusammen 20 MiB); alte Routen, Service und Web-Reiter entfernt
- Test-PKI-Fixtures (RSA und EC, Ketten, Schlüssel, CSR, PFX) mit Erzeugungsskript

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-09 14:52:29 +02:00
parent e079c307e4
commit 75ea83fc01
84 changed files with 2906 additions and 5160 deletions
+56 -112
View File
@@ -1250,123 +1250,67 @@
},
"certManager": {
"title": "Zertifikat-Manager",
"description": "Zertifikatspakete prüfen und in jedes Format bringen; einzelne Zertifikate analysieren, aufteilen, zusammenführen und konvertieren.",
"description": "Zertifikate, Zwischenzertifikate, Schlüssel und Anfragen sammeln, prüfen und in das gewünschte Format bringen.",
"tabs": {
"overview": "Übersicht",
"inspect": "Analysieren",
"split": "Aufteilen",
"merge": "Zusammenführen",
"convert": "Konvertieren"
"files": "Dateien",
"filesWithCount": "Dateien ({count})"
},
"dropZone": {
"placeholder": "Datei hierher ziehen oder klicken",
"formats": ".pem, .crt, .cer, .der, .pfx, .p12, .p7b, .p7c"
"roles": {
"end-entity": "Serverzertifikat",
"intermediate": "Zwischenzertifikat",
"root": "Stammzertifikat",
"privateKey": "Privater Schlüssel",
"csr": "Zertifikatsanfrage (CSR)"
},
"paste": {
"placeholder": "PEM-Inhalt einfügen (-----BEGIN ...)"
},
"password": {
"label": "Passwort (PFX/P12)"
},
"or": "oder",
"actions": {
"inspect": "Analysieren",
"split": "Aufteilen",
"merge": "Zusammenführen",
"convert": "Konvertieren",
"download": "Herunterladen",
"downloadZip": "Alle als ZIP herunterladen",
"processing": "Wird verarbeitet...",
"zipFilename": "Zertifikate.zip"
},
"certRole": {
"root": "Root-CA",
"intermediate": "Zwischen-CA",
"end-entity": "Zertifikat"
},
"emptyState": {
"inspect": "Kein Zertifikat geladen.",
"inspectBody": "Laden Sie eine Datei hoch oder fügen Sie PEM-Text ein.",
"split": "Keine Datei geladen.",
"splitBody": "Laden Sie eine Fullchain- oder P7B-Datei hoch.",
"merge": "Keine Zertifikate ausgewählt.",
"mergeBody": "Laden Sie mindestens zwei Dateien hoch.",
"convert": "Keine Datei geladen.",
"convertBody": "Laden Sie eine Datei hoch und wählen Sie ein Ausgabeformat."
},
"error": {
"generic": "Verarbeitung fehlgeschlagen. Prüfen Sie das Dateiformat oder das Passwort.",
"wrongPassword": "Falsches Passwort. PFX/P12-Datei konnte nicht entschlüsselt werden.",
"unknownFormat": "Unbekanntes Format. Die Datei konnte nicht als Zertifikat erkannt werden."
},
"overview": {
"dropTitle": "Zertifikatsdateien oder ZIP hierher ziehen oder klicken",
"dropHint": "Alles auf einmal, so wie es vom Aussteller kommt: .zip, .pem, .crt, .cer, .key, .csr, .pfx, .p12, .p7b",
"removeFile": "{name} entfernen",
"reset": "Alle entfernen",
"files": {
"dropTitle": "Dateien hierher ziehen oder klicken",
"dropHint": "Sie können mehrere Dateien nacheinander hinzufügen, jede bleibt in der Liste. Tessera erkennt den Inhalt selbst, die Dateiendung spielt keine Rolle.",
"limits": "Bis zu {maxFiles} Dateien, je Datei höchstens {maxFile} MB, zusammen höchstens {maxTotal} MB.",
"memoryNote": "Die Dateien bleiben nur in diesem Browserfenster. Tessera speichert nichts davon; nach dem Neuladen oder Schließen der Seite ist die Liste leer.",
"empty": "Noch keine Dateien. Fügen Sie Ihre Zertifikate hinzu, danach sehen Sie hier, was darin steckt.",
"listTitle": "Ihre Dateien ({count})",
"remove": "„{name}“ entfernen",
"removeShort": "Entfernen",
"removeAll": "Alle entfernen",
"analyzing": "Dateien werden geprüft …",
"error": "Die Dateien konnten nicht geprüft werden. Bitte prüfen Sie, ob es Zertifikatsdateien sind.",
"locked": "Geschützt: {files}. Geben Sie das Passwort ein, um auch diesen Inhalt zu lesen.",
"lockedNotNeeded": "{files} ist mit einem Passwort geschützt. Sie brauchen es nicht: Zertifikat und privater Schlüssel liegen schon als einzelne Dateien vor und sind unten aufgeführt. Eine neue PFX-Datei mit eigenem Passwort können Sie beim Serverzertifikat erstellen.",
"lockedPassword": "Passwort der geschützten Datei",
"unlock": "Entsperren",
"unlockAnyway": "Trotzdem mit Passwort öffnen",
"nothingFound": "In den Dateien wurde kein Zertifikat, Schlüssel und keine Zertifikatsanfrage gefunden.",
"ignored": "Nicht verwendet (kein Zertifikat erkannt): {files}",
"type": {
"end-entity": "Serverzertifikat",
"intermediate": "Zwischenzertifikat",
"root": "Stammzertifikat",
"privateKey": "Privater Schlüssel",
"csr": "Zertifikatsanfrage (CSR)"
"checking": "Wird geprüft …",
"retry": "Erneut versuchen",
"expired": "abgelaufen",
"rejectedTitle": "Nicht hinzugefügt:",
"rejected": {
"duplicate": "„{name}“ ist schon in der Liste.",
"tooMany": "„{name}“: die Liste ist mit {max} Dateien voll.",
"tooLarge": "„{name}“ ist größer als {size} MB.",
"totalTooLarge": "„{name}“: zusammen wären es mehr als {size} MB."
},
"explain": {
"end-entity": "Das eigentliche Zertifikat für Ihre Domain – das gehört auf den Webserver.",
"intermediate": "Bestätigt Ihr Serverzertifikat gegenüber dem Browser. Wird zusammen mit dem Serverzertifikat eingespielt (Kette).",
"root": "Oberste Zertifizierungsstelle. Ist in Browsern und Betriebssystemen meist schon vorhanden.",
"privateKey": "Der geheime Schlüssel zum Serverzertifikat. Wird auf dem Server gebraucht, darf aber nie weitergegeben werden.",
"csr": "Die Anfrage, mit der das Zertifikat beim Aussteller bestellt wurde. Wird nur für eine Neuausstellung gebraucht."
},
"issuer": "Ausgestellt von",
"validity": "Gültig",
"names": "Gilt für",
"key": "Schlüssel",
"belongsTo": "Gehört zu",
"source": "Gefunden in",
"valid": "Gültig",
"expired": "Abgelaufen",
"expiresSoon": "Läuft in {days} Tagen ab",
"keySecret": "Geheim halten: Wer diesen Schlüssel hat, kann sich als Ihre Website ausgeben.",
"downloading": "Wird erstellt …",
"exportError": "Diese Datei konnte nicht erstellt werden.",
"format": {
"crt": "PEM (.crt)",
"cer": "DER (.cer)",
"fullchain": "Mit Kette (.pem)",
"p7b": "PKCS#7 (.p7b)",
"pfx": "PFX (.pfx)",
"key": "PEM (.key)",
"key-rsa": "RSA-PEM (.rsa.key)",
"key-der": "DER (.key.der)",
"csr": "PEM (.csr)",
"csr-der": "DER (.csr.der)"
},
"formatHint": {
"crt": "Textformat, z. B. für Apache, Nginx und die meisten Geräte",
"cer": "Binärformat, z. B. für Windows und Java",
"fullchain": "Zertifikat und Kette in einer Datei, z. B. für Nginx",
"p7b": "Zertifikat und Kette ohne Schlüssel, z. B. für Windows/IIS",
"pfx": "Zertifikat, Kette und Schlüssel in einer passwortgeschützten Datei, z. B. für Windows/IIS und Exchange",
"key": "Schlüssel im Standardformat (PKCS#8)",
"key-rsa": "Schlüssel im älteren RSA-Format (PKCS#1), für ältere Software",
"key-der": "Schlüssel als Binärdatei",
"csr": "Zertifikatsanfrage als Text",
"csr-der": "Zertifikatsanfrage als Binärdatei"
},
"pfxWithKey": "Die PFX-Datei enthält Zertifikat, Kette und privaten Schlüssel. Legen Sie ein Passwort fest – es wird beim Einspielen abgefragt.",
"pfxWithoutKey": "Zu diesem Zertifikat liegt kein Schlüssel vor – die PFX-Datei enthält nur Zertifikat und Kette. Legen Sie ein Passwort fest.",
"pfxPassword": "Passwort für die PFX-Datei",
"pfxDownload": "PFX herunterladen"
"ignored": {
"unknown": "Darin wurde kein Zertifikat erkannt.",
"nestedZip": "Ein ZIP in einem ZIP wird nicht geöffnet.",
"encryptedZip": "Der ZIP-Inhalt ist mit einem Passwort geschützt und wird übersprungen.",
"brokenZip": "Das ZIP lässt sich nicht lesen.",
"tooLarge": "Die Datei ist zu groß und wird übersprungen.",
"suspicious": "Die Datei ist ungewöhnlich stark gepackt und wird übersprungen.",
"zipTooLarge": "Das ZIP enthält zu viele Daten und wird nicht geöffnet.",
"tooManyEntries": "Das ZIP enthält zu viele Dateien und wird nicht geöffnet.",
"unsupportedKey": "Dieser Schlüsseltyp wird nicht unterstützt."
}
},
"errors": {
"generic": "Die Dateien konnten nicht geprüft werden. Bitte versuchen Sie es erneut.",
"invalidInput": "Die Eingabe ist unvollständig oder ungültig. Bitte prüfen Sie Ihre Angaben.",
"notACertificate": "Mindestens eine Angabe ist kein Zertifikat. Bitte prüfen Sie die Dateien.",
"noChain": "Es gibt keine Kette zum Herunterladen. Fügen Sie das Zwischenzertifikat hinzu.",
"keyMissing": "Dafür wird der passende private Schlüssel gebraucht. Fügen Sie ihn im Reiter „Dateien“ hinzu.",
"keyMismatch": "Der Schlüssel gehört nicht zu diesem Zertifikat.",
"passwordRequired": "Bitte geben Sie ein Passwort an.",
"formatNotPossible": "Dieses Format ist für den Schlüsseltyp nicht möglich. Wählen Sie ein anderes Format.",
"templateNeedsKey": "Diese Vorlage braucht das Zertifikat und den passenden privaten Schlüssel.",
"tooLarge": "Die Dateien sind zusammen zu groß. Entfernen Sie einzelne Dateien und versuchen Sie es erneut.",
"aiaMissing": "Im Zertifikat steht keine Adresse, unter der das fehlende Zertifikat zu holen wäre.",
"aiaInternal": "Die Adresse im Zertifikat verweist nicht auf einen öffentlichen Server und wird nicht abgerufen.",
"aiaNotIssuer": "Die Adresse lieferte kein passendes Zertifikat des Ausstellers.",
"aiaUnreachable": "Der Server des Ausstellers ist nicht erreichbar. Laden Sie das Zertifikat selbst herunter und fügen Sie es hinzu.",
"aiaTooLarge": "Die Antwort des Ausstellers ist zu groß und wurde verworfen."
}
},
"tenderRadar": {