Sicherheit / Signieren: CMS, RFC 3161-Zeitstempel, LTV und Vertrauen
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Diese Seite beschreibt die Signaturoberfläche, die in NextPDF Core ausgeliefert wird: das Erzeugen einer CMS-Signatur, das Anwenden eines RFC 3161-Zeitstempels, die Prüfung einer Zertifikatskette gegen RFC 5280 sowie die Sperrprüfung über OCSP und CRL. Sie beschreibt das Verhalten, nicht die Implementierung. Die Implementierungsklassen von Core sind intern — Produktionscode nutzt den Vertrag SignerInterface, nicht die konkreten NextPDF\Security\Signature-Typen. Ob eine erzeugte Signatur verifiziert wird, entscheidet der Prüfer anhand der Vertrauensanker, mit denen er konfiguriert ist. Dieses Ergebnis liegt außerhalb der Kontrolle des Erzeugers; diese Seite benennt das an den relevanten Stellen ausdrücklich.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Core baut aus dem Byte-Bereich eine CMS-SignedData-Struktur auf und legt sie anschließend DER-codiert im Eintrag Contents des Signatur-Dictionarys ab — ISO 32000-2 §12.8.1. Die Struktur enthält signierte SignerInfo-Attribute — darunter content-type und message-digest — RFC 5652 §5.3. Ein Prüfer berechnet den Inhalts-Digest neu und vergleicht ihn mit dem Attribut message-digest. Dieser Vergleich muss übereinstimmen, damit die Signatur gültig ist — RFC 5652 §5.4. Die SignerInfo enthält außerdem die Kennung des Digest-Algorithmus und den Block der signierten Attribute — RFC 5652 §5. Für die ausgelieferten Software-Pfade signiert Core über phpseclib3: RSA, RSASSA-PSS, ECDSA und Ed25519.
Ein RFC 3161-Zeitstempel ist ein Anfrage-Antwort-Austausch mit einer Time-Stamping Authority, die eine TSTInfo-Struktur zurückgibt — RFC 3161 §2.4.1. Jedes Token trägt eine serialNumber, die für die ausstellende TSA eindeutig ist — RFC 3161 §2.4.2 — sowie eine als UTC angegebene genTime, also den Zeitpunkt, zu dem das Token erstellt wurde — RFC 3161 §2.4.2.
Die Vertrauensvalidierung umfasst zwei Prüfungen. Die Pfadvalidierung verläuft vom Signaturzertifikat bis zu einem Vertrauensanker und prüft dabei die Basisbeschränkungen sowie die Eingaben der Pfadkonstruktion — RFC 5280 §6.1. Die Sperrprüfung fragt einen OCSP-Responder ab oder liest eine CRL: Eine OCSP-Antwort meldet good, revoked oder unknown — RFC 6960 §2.2 —, und die Felder thisUpdate und nextUpdate der Antwort begrenzen, wie aktuell dieser Status ist — RFC 6960 §4.2. Die Vertrauensanker und die Richtlinie für die Aktualität der Sperrinformationen werden vom Aufrufer bereitgestellt. Die Engine validiert gegen die übergebenen Daten und liefert keine eingebaute Vertrauensliste aus.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Typ | Art | Rolle | Stabilität | Seit |
|---|---|---|---|---|
SignerInterface | interface (NextPDF\Contracts) | Signaturvertrag, auf den sich Aufrufer stützen | stabil | 1.0.0 |
SignatureLevel | enum | PAdES-Level-Selektor und Verfügbarkeitsprüfung | stabil | 1.0.0 |
Rfc5280PathValidator | interface | Einstiegspunkt der Zertifizierungspfad-Validierung (validate(...)) | stabil (eingefroren 3.1.0) | 3.1.0 |
RevocationStatus | enum | OCSP- / CRL-Ergebnis: good, revoked, unknown | stabil | 3.1.0 |
CaTrustAnchorBundle | type | Vom Aufrufer bereitgestellte Menge an Vertrauensankern | stabil | 3.1.0 |
TstInfo | type | Geparste RFC 3161-Zeitstempelfelder | stabil | 3.2.0 |
SignerInterface::sign() liefert ein SignatureResult, dessen toHex() die Hex-Zeichenkette für /Contents ergibt und dessen Eigenschaft cmsSignedData die rohen DER-Bytes enthält. Die konkreten NextPDF\Security\Signature-Klassen, die dieses Verhalten implementieren, sind intern (stability: internal im Modul-Manifest); sie sind nicht Teil der öffentlichen API und können sich ohne Major-Version-Sprung ändern. Stützen Sie sich auf die oben genannten Verträge und Enums.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\SignerInterface;
/** * Produce the CMS SignedData hex for a PDF /Contents field. * * @param SignerInterface $signer A Core or Premium signer. * @param string $byteRange The PDF byte range to sign. * * @return string Hex-encoded CMS SignedData. */function sign(SignerInterface $signer, string $byteRange): string{ return $signer->sign($byteRange)->toHex();}Der Aufrufer stützt sich auf den Vertrag. Sowohl ein Core-Software-Signierer als auch ein Premium-HSM-Signierer erfüllen SignerInterface; daher bleibt dieser Code über alle Editionen hinweg unverändert.
Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\SignerInterface;use NextPDF\Contracts\TimestampProviderInterface;use NextPDF\Exception\NextPdfException;use Psr\Log\LoggerInterface;
final readonly class TimestampedSigner{ public function __construct( private SignerInterface $signer, private TimestampProviderInterface $timestamps, private LoggerInterface $logger, ) {}
/** * Sign a byte range, then timestamp the CMS structure. * * The timestamp's trust still depends on the verifier accepting the * Time-Stamping Authority; this method only produces the structure. * * @param string $byteRange The PDF byte range to sign. * * @return array{cms: string, tst: string} */ public function sign(string $byteRange): array { try { $signature = $this->signer->sign($byteRange); $token = $this->timestamps->getTimestamp($signature->cmsSignedData);
return ['cms' => $signature->toHex(), 'tst' => $token]; } catch (NextPdfException $e) { $this->logger->error('Signing failed', ['error' => $e->getMessage()]);
throw $e; } }}Der Zeitstempel-Provider wird injiziert, sodass ein Deployment seine eigene Time-Stamping Authority festlegen kann. Der Catch-Block protokolliert den Fehler und wirft ihn erneut. Er verschluckt den Fehler nie; dadurch bleibt der Signierpfad fail-closed.
Randfälle & Fallstricke
Abschnitt betitelt „Randfälle & Fallstricke“- Eine erzeugte Signatur ist keine verifizierte Signatur. Pfadvalidierung und Sperrprüfung erfolgen beim Prüfer mit dessen Vertrauensankern. Der Erzeuger kann das Ergebnis nicht zusichern.
- Der Byte-Bereich-Digest schließt den Signaturwert aus. Ein Digest, der die
Contents-Oktette abdeckt, kann nicht verifiziert werden — ISO 32000-2 §12.8.1. - Der Sperrstatus hat ein Aktualitätsfenster. Eine OCSP-Antwort ist nur so aktuell wie ihr Intervall aus
thisUpdate/nextUpdate— RFC 6960 §4.2. Eine veraltete Antwort ist kein Ersatz für eine frische Prüfung zum Validierungszeitpunkt. - Die Engine liefert keine eingebaute Vertrauensliste aus.
CaTrustAnchorBundlewird vom Aufrufer bereitgestellt; ein leeres Bundle bedeutet, dass keine Kette validiert — das ist beabsichtigt. - OCSP
unknownist nichtgood. Behandeln Sieunknownals Nicht-Feststellung, nicht als impliziten Erfolg — RFC 6960 §2.2. - HSM-Schlüsselverwahrung, aufgeschobenes Signieren und Cloud-Signieren sowie der Erzeuger für PAdES B-LT / B-LTA sind nicht in Core enthalten. Werden diese Pfade in der Core-Distribution ausgewählt, schlägt dies fail-closed mit einer Meldung fehl, die die fehlende Enterprise-Komponente benennt.
Performance
Abschnitt betitelt „Performance“Eine Software-Signatur liegt im einstelligen Millisekundenbereich. Ein Zeitstempel fügt einen Netzwerk-Roundtrip zur TSA hinzu. Die Pfadvalidierung läuft lokal, sobald die Zertifikate im Speicher liegen; die Sperrprüfung fügt pro Zertifikat in der Kette einen OCSP- oder CRL-Abruf hinzu. Das Wandzeitbudget von 1500 ms deckt eine einzelne zeitgestempelte Signatur mit einer entfernten TSA über eine bereits aufgebaute Verbindung ab. Eine Sperrprüfung gegen einen langsamen Endpunkt überschreitet dieses Budget und gehört daher außerhalb des Anfragepfads. Das Reproduzierbarkeitsprofil ist structural: Ein Zeitstempel bettet den Signierzeitpunkt ein; daher unterscheiden sich zwei Läufe in den Zeitstempel-Bytes, während die Dokumentstruktur identisch ist.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Dies ist die primäre kryptografische Grenze der Engine; daher ist das Bedrohungsmodell explizit. Der Byte-Bereich wird von der Engine berechnet und nie vom Aufrufer übernommen. Der Signierpfad ist fail-closed: Ein Fehler eines Primitivs oder eine fehlende Fähigkeit löst eine typisierte Ausnahme aus und stuft nie stillschweigend auf einen schwächeren Algorithmus herab. Auf einem Level, das einen Zeitstempel erfordert (B-T, B-LT, B-LTA), ist eine Time-Stamping Authority, die ein leeres Token zurückgibt, ein terminaler Fehler: Die Signatur wird verweigert und nicht stillschweigend ungestempelt und herabgestuft ausgegeben, es sei denn, ein Fault-Handler ist verdrahtet, um eine dokumentierte Degradation zu autorisieren. Das Vertrauen ist konstruktionsbedingt vom Aufrufer kontrolliert — Anker und Sperrrichtlinie sind Eingaben, keine Engine-Voreinstellungen —, weil ein Erzeuger, der sein eigenes Vertrauen zusicherte, eine Tatsache zusichern würde, die nur der Prüfer feststellen kann. Das Vertrauen in den Zeitstempel reduziert sich auf das Vertrauen in die Time-Stamping Authority, die injizierbar ist, sodass ein Deployment seine eigene festlegen kann. Diese Seite ist mit export_control_class: legal-review-required gekennzeichnet, weil sie kryptografisches Signieren betrifft; jede normative Quelle wird paraphrasiert und keine wird wiedergegeben, entsprechend der Zitierhygiene.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Standard | Klausel | Nachweis |
|---|---|---|---|
Die CMS-Signatur wird DER-codiert im Eintrag Contents des Signatur-Dictionarys gespeichert. | ISO 32000-2 | §12.8.1 | |
| SignerInfo trägt die signierten Attribute content-type und message-digest. | RFC 5652 | §5.3 | |
| Der Prüfer berechnet den Inhalts-Digest neu und vergleicht ihn mit dem Attribut message-digest. | RFC 5652 | §5.4 | |
| Ein Zeitstempel-Token wird von einer RFC 3161-TSA erzeugt und trägt eine eindeutige serialNumber sowie eine UTC-genTime. | RFC 3161 | §2.4.1, §2.4.2 | ,, |
| Die Zertifizierungspfad-Validierung prüft Basisbeschränkungen und die Pfadeingaben vom Signierer bis zu einem Vertrauensanker. | RFC 5280 | §6.1 | , |
| OCSP meldet certStatus als good, revoked oder unknown; thisUpdate / nextUpdate begrenzen diese Angabe. | RFC 6960 | §2.2, §4.2 | , |
Alle Klauseln sind paraphrasiert. NextPDF reproduziert keinen normativen Text. Ziehen Sie für den verbindlichen Wortlaut die veröffentlichten Standards zurate.
Kommerzieller Kontext
Abschnitt betitelt „Kommerzieller Kontext“Core liefert den Software-CMS-Signierer (RSA, RSASSA-PSS, ECDSA, Ed25519), die Verarbeitung von RFC 3161-Zeitstempeln, die RFC 5280-Pfadvalidierung sowie die OCSP- / CRL-Sperrprüfung. HSM- und PKCS#11-Schlüsselverwahrung, aufgeschobenes Signieren und Cloud-Signieren, der Erzeuger für PAdES B-LT und B-LTA sowie das Krypto-Policy-Profil für FIPS 140-3 werden in den Editionen Pro und Enterprise ausgeliefert. Core löst diese Funktionen zur Laufzeit über den Vertrag auf; daher trägt die Open-Source-Engine keine kommerzielle Abhängigkeit, und die API ändert sich beim Upgrade nicht.
Siehe auch
Abschnitt betitelt „Siehe auch“- PAdES-Baseline-Mapping — Core gegenüber Premium über B-B, B-T, B-LT, B-LTA hinweg.
- Contracts / Signing — die
SignerInterface-SPI und die Stabilitätsstufen. - Security — Verschlüsselung und die breitere Signaturoberfläche.
- Conformance — Profildurchsetzung, die mit signierter Archivierung zusammenspielt.
- CMS · RFC 3161-Zeitstempel · LTV · DSS · VRI · HSM — Glossarbegriffe.