Salta ai contenuti
getnextpdf.com

Enterprise edizione

Avvio rapido di NextPDF Enterprise

Questo tutorial conduce da un progetto vuoto a due risultati Enterprise funzionanti. Per prima cosa si verifica un PDF firmato esistente e se ne legge la MainIndication. Poi si eleva un documento firmato a PAdES B-LT con il produttore a lungo termine. Ogni passaggio mostra l’output esatto o l’eccezione da attendersi. NextPDF documenta la capacità, non la certificazione: non detiene alcuna certificazione PAdES o eIDAS e non ne concede alcuna.

Questa capacità è distribuita in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un involucro di licenza di livello Enterprise. Una distribuzione priva di tale entitlement non carica le classi della capacità. Confronta le edizioni e ottieni una licenza.

  • Composer è configurato per il repository privato di NextPDF. Segui prima Installazione e autenticazione.
  • Disponi del tuo involucro di licenza Enterprise, scaricato dal tuo account su app.getnextpdf.com. Licenze e attivazione spiega cos’è l’involucro e dove va collocato.
  • Per il passaggio 3 serve un PDF firmato da verificare. Per la parte B-LT servono anche il certificato del firmatario e l’accesso di rete ai responder OCSP/CRL.

Richiedi il pacchetto Enterprise. Dipende da nextpdf/core e nextpdf/pro, quindi Composer porta con sé l’intero stack:

Terminal window
composer require nextpdf/enterprise
composer show nextpdf/enterprise

Se composer show stampa il pacchetto e la sua versione, l’installazione è riuscita. Ora colloca l’involucro di licenza firmato dove la tua distribuzione lo carica, esattamente come descrive Licenze e attivazione. La sola installazione del pacchetto non concede le capacità Enterprise; è la licenza attivata a selezionare l’edizione.

Chiedi al valutatore di entitlement cosa concede la tua licenza. Il tuo bootstrap ottiene la NextPDF\Enterprise\Licensing\LicenseKey verificata durante l’attivazione; passala:

<?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;

Con una licenza Enterprise attiva vedi:

status: active
edition: enterprise
runtime: allowed

Il metodo alla base di questo passaggio:

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

Lancia o fallisce con: non lancia mai. Una licenza mancante restituisce un EntitlementResult fail-closed con EntitlementStatus::NoLicense e runtimeAllowed false (vedi passaggio 4).

Estrai la firma da un PDF firmato, quindi esegui la validazione AdES di base. Il motore implementa i livelli di validazione di ETSI EN 319 102-1; validateBasic() è il flusso della clausola 5.2 — struttura, digest, crittografia della firma e catena dei certificati:

<?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;

Per una firma ben formata che supera i controlli di base — strutturali, di digest, crittografici e di catena — configurati in questo esempio, vedi:

TOTAL_PASSED
(none)

MainIndication ha esattamente tre casi: TOTAL_PASSED, TOTAL_FAILED e INDETERMINATE. Il motore è fail-closed: un controllo che non può stabilire positivamente produce INDETERMINATE, mai un passaggio silenzioso. Un esito positivo qui è un risultato di validazione secondo i controlli di questo motore, non un’affermazione di fiducia o certificazione — le ancore di fiducia e l’evidenza a lungo termine appartengono ai livelli più profondi nella pagina di verifica.

public function extract(string $pdfData): array

Lancia o fallisce con: InvalidArgumentException se l’input non è un PDF valido. Un /ByteRange o /Contents malformato produce stringhe vuote (fail-closed), mai un risultato positivo.

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

Lancia o fallisce con: non lancia mai in caso di fallimento della verifica. Ogni difetto è mappato su un’indicazione di ValidationReport, ad esempio HASH_FAILURE o SIG_CRYPTO_FAILURE.

Ora eleva un documento appena firmato a B-LT. Il produttore a lungo termine raccoglie la catena dei certificati più l’evidenza OCSP/CRL e scrive il Document Security Store (DSS). Prosegue la passata di firma descritta nella pagina Firma, che fornisce il buffer di output, il registro degli oggetti e l’esadecimale di /Contents della firma:

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);

Il valore restituito è il numero dell’oggetto DSS per la voce /DSS del catalogo del documento. Il produttore imposta come predefinita l’applicazione strict della revoca: la mancanza di materiale di revoca solleva un’eccezione anziché emettere silenziosamente un file “B-LT” vuoto.

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

Lancia o fallisce con: NextPDF\Enterprise\Security\Ltv\LtvException quando la validazione della catena fallisce, quando il certificato è revocato o quando manca il materiale di revoca sotto l’impostazione strict predefinita.

status: no_license — l’involucro non è caricato

Sezione intitolata “status: no_license — l’involucro non è caricato”

Il passaggio 2 stampa status: no_license e runtime: disabled, e il risultato riporta l’avviso No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing. Una chiamata soggetta a gating di entitlement lancia quindi NextPDF\Accelerator\Exception\SpectrumAuthenticationException con codice SPEC-LIC-001, ad esempio Capability '...' requires a valid license. Soluzione: colloca e attiva l’involucro secondo Licenze e attivazione, quindi riesegui il passaggio 2.

InvalidArgumentException: Input does not start with %PDF header

Sezione intitolata “InvalidArgumentException: Input does not start with %PDF header”

SignatureExtractor::extract() ha ricevuto qualcosa che non è un PDF — un percorso errato, una lettura vuota o un download compresso. Controlla il file che hai caricato. Una lista $signatures vuota è diversa: il file è un PDF, ma non riporta alcun dizionario /Type /Sig, quindi non c’è nulla da verificare.

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

Sezione intitolata “LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0”

enableLtv() non è riuscito a ottenere una risposta OCSP o una CRL per un certificato della catena, e l’impostazione strict predefinita rifiuta di scrivere un’affermazione B-LT senza evidenza. Verifica la raggiungibilità del responder dall’host, oppure passa enforcementMode: RevocationEnforcementMode::PERMISSIVE solo se accetti esplicitamente un’esecuzione con soli avvisi — non etichettare mai tale output come B-LT per flussi di produzione o conformità, a meno che l’evidenza di revoca mancante non sia esplicitamente accettata e documentata. Correlato: richiedere B-LTA senza un client TSA fallisce con LtvException: TSA client required for document timestamps.