Zum Inhalt springen
getnextpdf.com

Enterprise Edition

NextPDF Enterprise – Schnellstart

Dieses Tutorial führt Sie von einem leeren Projekt zu zwei funktionierenden Enterprise-Ergebnissen. Zuerst verifizieren Sie ein vorhandenes signiertes PDF und lesen dessen MainIndication. Anschließend heben Sie ein signiertes Dokument mit dem Langzeitproduzenten auf PAdES B-LT an. Jeder Schritt zeigt die genaue Ausgabe oder Ausnahme, die Sie erwarten sollten. NextPDF dokumentiert Fähigkeiten, keine Zertifizierung: Es besitzt keine PAdES- oder eIDAS-Zertifizierung und erteilt auch keine.

Diese Fähigkeit ist in NextPDF Enterprise (nextpdf/enterprise) enthalten und wird mit einem Lizenz-Envelope der Enterprise-Stufe aktiviert. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und Lizenz erwerben.

  • Composer ist für das private NextPDF-Repository konfiguriert. Folgen Sie zuerst Installieren und authentifizieren.
  • Sie haben Ihr Enterprise-Lizenz-Envelope, heruntergeladen aus Ihrem Konto unter app.getnextpdf.com. Lizenzierung und Aktivierung erläutert, was das Envelope ist und wohin es gehört.
  • Für Schritt 3 benötigen Sie ein signiertes PDF zum Verifizieren. Für den B-LT-Teil benötigen Sie zusätzlich Ihr Signaturzertifikat und Netzwerkzugriff auf OCSP-/CRL-Responder.

Fordern Sie das Enterprise-Paket an. Es hängt von nextpdf/core und nextpdf/pro ab, sodass Composer den gesamten Stack mitbringt:

Terminal-Fenster
composer require nextpdf/enterprise
composer show nextpdf/enterprise

Wenn composer show das Paket und dessen Version ausgibt, hat die Installation funktioniert. Legen Sie nun das signierte Lizenz-Envelope genau dort ab, wo Ihre Bereitstellung es lädt, exakt so, wie Lizenzierung und Aktivierung es beschreibt. Die alleinige Installation des Pakets erteilt keine Enterprise-Fähigkeiten; die aktivierte Lizenz wählt die Edition aus.

Fragen Sie den Berechtigungs-Evaluator, was Ihre Lizenz gewährt. Ihr Bootstrap erhält während der Aktivierung den verifizierten NextPDF\Enterprise\Licensing\LicenseKey; übergeben Sie ihn:

<?php
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Licensing\EntitlementEvaluator;
use NextPDF\Enterprise\Licensing\LicenseKey;
/** @var LicenseKey|null $license The verified license from activation. */
$result = (new EntitlementEvaluator())->evaluate($license);
echo 'status: ' . $result->status->value . PHP_EOL;
echo 'edition: ' . ($result->edition?->value ?? 'none') . PHP_EOL;
echo 'runtime: ' . ($result->runtimeAllowed ? 'allowed' : 'disabled') . PHP_EOL;

Mit einer aktiven Enterprise-Lizenz sehen Sie:

status: active
edition: enterprise
runtime: allowed

Die Methode hinter diesem Schritt:

public function evaluate(?LicenseKey $license, ?DateTimeImmutable $now = null): EntitlementResult

Löst aus oder scheitert mit: Sie löst niemals eine Ausnahme aus. Eine fehlende Lizenz liefert ein fail-closed EntitlementResult mit EntitlementStatus::NoLicense und runtimeAllowed false (siehe Schritt 4).

Extrahieren Sie die Signatur aus einem signierten PDF und führen Sie dann die grundlegende AdES-Validierung durch. Die Engine implementiert die Validierungsstufen von ETSI EN 319 102-1; validateBasic() ist der Ablauf nach Klausel 5.2 – Struktur, Digest, Signaturkryptografie und die Zertifikatskette:

<?php
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
use NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor;
use NextPDF\Enterprise\Signature\SignatureExtractor;
$pdf = file_get_contents(__DIR__ . '/contract-signed.pdf');
if ($pdf === false) {
throw new RuntimeException('Could not read contract-signed.pdf');
}
$signatures = (new SignatureExtractor())->extract($pdf);
if ($signatures === []) {
throw new RuntimeException('The PDF carries no signature dictionary.');
}
$engine = new AdESValidationEngine(extractor: new CmsSignatureDataExtractor());
$report = $engine->validateBasic(
$signatures[0]['signedBytes'], // the exact /ByteRange-covered bytes
$signatures[0]['contents'], // the DER CMS SignedData from /Contents
);
echo $report->mainIndication->name . PHP_EOL;
echo ($report->subIndication?->name ?? '(none)') . PHP_EOL;

Für eine wohlgeformte Signatur, die die in diesem Beispiel konfigurierten grundlegenden strukturellen, Digest-, kryptografischen und Ketten-Prüfungen besteht, sehen Sie:

TOTAL_PASSED
(none)

MainIndication hat genau drei Fälle: TOTAL_PASSED, TOTAL_FAILED und INDETERMINATE. Die Engine ist fail-closed: Eine Prüfung, die sie nicht positiv feststellen kann, ergibt INDETERMINATE, niemals ein stilles Bestehen. Ein Bestehen hier ist ein Validierungsergebnis unter den Prüfungen dieser Engine, keine Vertrauens- oder Zertifizierungsaussage – Vertrauensanker und Langzeitnachweise gehören zu den tieferen Stufen auf der Verifizierungsseite.

public function extract(string $pdfData): array

Löst aus oder scheitert mit: InvalidArgumentException, wenn die Eingabe kein gültiges PDF ist. Ein fehlerhafter /ByteRange oder /Contents ergibt leere Zeichenketten (fail-closed), niemals ein positives Ergebnis.

public function validateBasic(string $signedData, string $signature): ValidationReport

Löst aus oder scheitert mit: Bei einem Verifizierungsfehler löst sie niemals eine Ausnahme aus. Jeder Defekt wird auf eine ValidationReport-Indikation abgebildet, z. B. HASH_FAILURE oder SIG_CRYPTO_FAILURE.

Heben Sie nun ein frisch signiertes Dokument auf B-LT an. Der Langzeitproduzent sammelt die Zertifikatskette sowie OCSP-/CRL-Nachweise und schreibt den Document Security Store (DSS). Er setzt den Signaturvorgang fort, der auf der Signaturseite beschrieben ist und Ihnen den Ausgabepuffer, die Objektregistrierung und die Signatur-/Contents-Hexdarstellung liefert:

use NextPDF\Enterprise\Security\Ltv\LtvManager;
use NextPDF\Security\Signature\CertificateInfo;
use NextPDF\Security\Signature\SignatureLevel;
$certInfo = CertificateInfo::fromPkcs12('/secure/signer.p12', $p12Password);
// $httpClient is any PSR-18 client; it fetches OCSP responses and CRLs.
$ltv = new LtvManager($certInfo, $httpClient, level: SignatureLevel::PAdES_B_LT);
// $buffer, $registry, and $signatureContentsHex come from the signing pass.
$dssObjectNumber = $ltv->enableLtv($buffer, $registry, $signatureContentsHex);

Der Rückgabewert ist die DSS-Objektnummer für den /DSS-Eintrag des Dokumentkatalogs. Der Produzent verwendet standardmäßig eine strikte Sperrprüfung: Fehlendes Sperrmaterial löst eine Ausnahme aus, anstatt stillschweigend eine hohle „B-LT”-Datei auszugeben.

public function enableLtv(BinaryBuffer $buffer, ObjectRegistry $registry, string $signatureContentsHex): int

Löst aus oder scheitert mit: NextPDF\Enterprise\Security\Ltv\LtvException, wenn die Kettenvalidierung fehlschlägt, wenn das Zertifikat gesperrt ist oder wenn unter der strikten Voreinstellung Sperrmaterial fehlt.

status: no_license – das Envelope ist nicht geladen

Abschnitt betitelt „status: no_license – das Envelope ist nicht geladen“

Schritt 2 gibt status: no_license und runtime: disabled aus, und das Ergebnis trägt die Warnung No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing. Ein berechtigungsgesteuerter Aufruf löst dann NextPDF\Accelerator\Exception\SpectrumAuthenticationException mit dem Code SPEC-LIC-001 aus, z. B. Capability '...' requires a valid license. Behebung: Legen Sie das Envelope gemäß Lizenzierung und Aktivierung ab und aktivieren Sie es, und führen Sie dann Schritt 2 erneut aus.

InvalidArgumentException: Input does not start with %PDF header

Abschnitt betitelt „InvalidArgumentException: Input does not start with %PDF header“

SignatureExtractor::extract() hat etwas erhalten, das kein PDF ist – ein falscher Pfad, ein leerer Lesevorgang oder ein komprimierter Download. Prüfen Sie die geladene Datei. Eine leere $signatures-Liste ist etwas anderes: Die Datei ist ein PDF, trägt aber kein /Type /Sig-Dictionary, sodass es nichts zu verifizieren gibt.

LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0

Abschnitt betitelt „LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0“

enableLtv() konnte keine OCSP-Antwort und keine CRL für ein Kettenzertifikat beschaffen, und die strikte Voreinstellung weigert sich, einen B-LT-Anspruch ohne Nachweis zu schreiben. Prüfen Sie die Erreichbarkeit der Responder vom Host aus, oder übergeben Sie enforcementMode: RevocationEnforcementMode::PERMISSIVE nur dann, wenn Sie einen reinen Warnlauf ausdrücklich akzeptieren – kennzeichnen Sie eine solche Ausgabe niemals als B-LT für Produktions- oder Compliance-Workflows, es sei denn, der fehlende Sperrnachweis wird ausdrücklich akzeptiert und dokumentiert. Verwandt: Das Anfordern von B-LTA ohne einen TSA-Client scheitert mit LtvException: TSA client required for document timestamps.