Ir al contenido
getnextpdf.com

Enterprise edición

Guía de inicio rápido de NextPDF Enterprise

Este tutorial le lleva desde un proyecto vacío hasta dos resultados de Enterprise en funcionamiento. Primero verificará un PDF firmado existente y leerá su MainIndication. Después elevará un documento firmado a PAdES B-LT con el productor de largo plazo. Cada paso muestra la salida o la excepción exacta que debe esperar. NextPDF documenta capacidades, no certificación: no posee ninguna certificación PAdES ni eIDAS y no concede ninguna.

Esta capacidad se distribuye en NextPDF Enterprise (nextpdf/enterprise) y se activa con un envoltorio de licencia de nivel Enterprise. Una implementación sin esa titularidad no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.

  • Composer está configurado para el repositorio privado de NextPDF. Siga primero Instalar y autenticar.
  • Tiene su envoltorio de licencia Enterprise, descargado desde su cuenta en app.getnextpdf.com. Licencias y activación explica qué es el envoltorio y dónde va.
  • Para el paso 3 necesita un PDF firmado para verificar. Para la parte de B-LT también necesita su certificado de firmante y acceso de red a los respondedores OCSP/CRL.

Requiera el paquete Enterprise. Depende de nextpdf/core y nextpdf/pro, por lo que Composer trae toda la pila:

Ventana de terminal
composer require nextpdf/enterprise
composer show nextpdf/enterprise

Si composer show imprime el paquete y su versión, la instalación funcionó. Ahora coloque el envoltorio de licencia firmado donde su implementación lo carga, exactamente como describe Licencias y activación. Instalar el paquete por sí solo no concede las capacidades de Enterprise; la licencia activada selecciona la edición.

Pregunte al evaluador de titularidad qué concede su licencia. Su arranque obtiene la NextPDF\Enterprise\Licensing\LicenseKey verificada durante la activación; pásela:

<?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 licencia Enterprise activa verá:

status: active
edition: enterprise
runtime: allowed

El método detrás de este paso:

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

Lanza o falla con: nunca lanza. Una licencia ausente devuelve un EntitlementResult fail-closed con EntitlementStatus::NoLicense y runtimeAllowed en false (véase el paso 4).

Extraiga la firma de un PDF firmado y luego ejecute la validación AdES básica. El motor implementa los niveles de validación de ETSI EN 319 102-1; validateBasic() es el flujo de la cláusula 5.2: estructura, resumen, criptografía de la firma y la cadena de certificados:

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

Para una firma bien formada que supera las comprobaciones básicas de estructura, resumen, criptografía y cadena configuradas en este ejemplo, verá:

TOTAL_PASSED
(none)

MainIndication tiene exactamente tres casos: TOTAL_PASSED, TOTAL_FAILED e INDETERMINATE. El motor es fail-closed: una comprobación que no puede establecer de forma positiva produce INDETERMINATE, nunca un pase silencioso. Un pase aquí es un resultado de validación bajo las comprobaciones de este motor, no una declaración de confianza ni de certificación: los anclajes de confianza y la evidencia de largo plazo pertenecen a los niveles más profundos de la página de verificación.

public function extract(string $pdfData): array

Lanza o falla con: InvalidArgumentException si la entrada no es un PDF válido. Un /ByteRange o /Contents malformado produce cadenas vacías (fail-closed), nunca un resultado positivo.

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

Lanza o falla con: nunca lanza ante un fallo de verificación. Cada defecto se asigna a una indicación de ValidationReport, por ejemplo HASH_FAILURE o SIG_CRYPTO_FAILURE.

Ahora eleve un documento recién firmado a B-LT. El productor de largo plazo recopila la cadena de certificados más la evidencia OCSP/CRL y escribe el Document Security Store (DSS). Continúa la pasada de firma descrita en la página de Firma, que le proporciona el búfer de salida, el registro de objetos y el hex de /Contents de la 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);

El valor de retorno es el número de objeto del DSS para la entrada /DSS del catálogo del documento. El productor tiene por defecto una aplicación estricta de la revocación: la falta de material de revocación lanza una excepción en lugar de emitir silenciosamente un archivo “B-LT” hueco.

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

Lanza o falla con: NextPDF\Enterprise\Security\Ltv\LtvException cuando falla la validación de la cadena, cuando el certificado está revocado o cuando falta material de revocación bajo el valor estricto por defecto.

status: no_license — el envoltorio no está cargado

Sección titulada «status: no_license — el envoltorio no está cargado»

El paso 2 imprime status: no_license y runtime: disabled, y el resultado lleva la advertencia No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing. Una llamada protegida por titularidad lanza entonces NextPDF\Accelerator\Exception\SpectrumAuthenticationException con el código SPEC-LIC-001, por ejemplo Capability '...' requires a valid license. Solución: coloque y active el envoltorio según Licencias y activación, luego vuelva a ejecutar el paso 2.

InvalidArgumentException: Input does not start with %PDF header

Sección titulada «InvalidArgumentException: Input does not start with %PDF header»

SignatureExtractor::extract() recibió algo que no es un PDF: una ruta incorrecta, una lectura vacía o una descarga comprimida. Compruebe el archivo que cargó. Una lista $signatures vacía es distinta: el archivo es un PDF, pero no lleva ningún diccionario /Type /Sig, por lo que no hay nada que verificar.

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

Sección titulada «LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0»

enableLtv() no pudo obtener una respuesta OCSP ni una CRL para un certificado de la cadena, y el valor estricto por defecto se niega a escribir una declaración B-LT sin evidencia. Compruebe la accesibilidad del respondedor desde el host, o pase enforcementMode: RevocationEnforcementMode::PERMISSIVE solo si acepta explícitamente una ejecución de solo advertencia; nunca etiquete tal salida como B-LT para flujos de trabajo de producción o cumplimiento a menos que la evidencia de revocación ausente se acepte y documente explícitamente. Relacionado: solicitar B-LTA sin un cliente TSA falla con LtvException: TSA client required for document timestamps.