Перейти к содержимому
getnextpdf.com

Enterprise редакция

Быстрый старт NextPDF Enterprise

Этот учебник проведёт вас от пустого проекта до двух рабочих результатов Enterprise. Сначала вы проверите существующий подписанный PDF и прочитаете его MainIndication. Затем повысите подписанный документ до PAdES B-LT с помощью производителя долгосрочных подписей. Каждый шаг показывает точный вывод или исключение, которое вам следует ожидать. NextPDF документирует возможности, а не сертификацию: он не имеет сертификации PAdES или eIDAS и не предоставляет её.

Эта возможность поставляется в NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без этого права доступа не загружает классы данной возможности. Сравнить редакции и получить лицензию.

  • Composer настроен для приватного репозитория NextPDF. Сначала выполните Установка и аутентификация.
  • У вас есть лицензионный конверт Enterprise, загруженный из вашего аккаунта на app.getnextpdf.com. Лицензирование и активация объясняет, что такое конверт и куда он помещается.
  • Для шага 3 нужен подписанный PDF для проверки. Для части B-LT также нужны сертификат подписанта и сетевой доступ к респондерам OCSP/CRL.

Подключите пакет Enterprise. Он зависит от nextpdf/core и nextpdf/pro, поэтому Composer подтягивает весь стек:

Окно терминала
composer require nextpdf/enterprise
composer show nextpdf/enterprise

Если composer show выводит пакет и его версию, установка прошла успешно. Теперь поместите подписанный лицензионный конверт туда, откуда его загружает ваше развёртывание, ровно так, как описано в Лицензирование и активация. Установка одного лишь пакета не предоставляет возможности Enterprise; активированная лицензия выбирает редакцию.

Спросите у оценщика прав доступа, что предоставляет ваша лицензия. Ваш bootstrap получает проверенный NextPDF\Enterprise\Licensing\LicenseKey во время активации; передайте его:

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

С активной лицензией Enterprise вы увидите:

status: active
edition: enterprise
runtime: allowed

Метод, стоящий за этим шагом:

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

Выбрасывает или завершается с ошибкой: он никогда не выбрасывает исключение. Отсутствующая лицензия возвращает fail-closed EntitlementResult с EntitlementStatus::NoLicense и runtimeAllowed false (см. шаг 4).

Извлеките подпись из подписанного PDF, затем запустите базовую валидацию AdES. Движок реализует уровни валидации ETSI EN 319 102-1; validateBasic() — это поток пункта 5.2 — структура, дайджест, криптография подписи и цепочка сертификатов:

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

Для корректно сформированной подписи, которая проходит базовые структурные, дайджест-, криптографические и цепочечные проверки, настроенные в этом примере, вы увидите:

TOTAL_PASSED
(none)

MainIndication имеет ровно три случая: TOTAL_PASSED, TOTAL_FAILED и INDETERMINATE. Движок работает по принципу fail-closed: проверка, которую он не может положительно установить, даёт INDETERMINATE, а не молчаливый проход. Проход здесь — это результат валидации в рамках проверок данного движка, а не утверждение о доверии или сертификации — якоря доверия и долгосрочные доказательства относятся к более глубоким уровням на странице проверки.

public function extract(string $pdfData): array

Выбрасывает или завершается с ошибкой: InvalidArgumentException, если ввод не является корректным PDF. Некорректный /ByteRange или /Contents даёт пустые строки (fail-closed), а не положительный результат.

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

Выбрасывает или завершается с ошибкой: он никогда не выбрасывает исключение при сбое проверки. Каждый дефект отображается в индикацию ValidationReport, например HASH_FAILURE или SIG_CRYPTO_FAILURE.

Теперь повысьте только что подписанный документ до B-LT. Производитель долгосрочных подписей собирает цепочку сертификатов плюс доказательства OCSP/CRL и записывает Document Security Store (DSS). Он продолжает проход подписания, описанный на странице подписи, который даёт вам выходной буфер, реестр объектов и hex подписи /Contents:

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

Возвращаемое значение — это номер объекта DSS для записи /DSS каталога документа. Производитель по умолчанию применяет строгую принудительную проверку отзыва: отсутствие материала об отзыве вызывает исключение вместо молчаливого создания пустого файла «B-LT».

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

Выбрасывает или завершается с ошибкой: NextPDF\Enterprise\Security\Ltv\LtvException, когда валидация цепочки не удаётся, когда сертификат отозван или когда материал об отзыве отсутствует при строгом значении по умолчанию.

Шаг 2 выводит status: no_license и runtime: disabled, а результат несёт предупреждение No license configured. Enterprise runtime is disabled. Install a license or purchase one at https://nextpdf.dev/pricing. Вызов, ограниченный правами доступа, затем выбрасывает NextPDF\Accelerator\Exception\SpectrumAuthenticationException с кодом SPEC-LIC-001, например Capability '...' requires a valid license. Исправление: поместите и активируйте конверт согласно Лицензирование и активация, затем повторно запустите шаг 2.

SignatureExtractor::extract() получил нечто, что не является PDF — неверный путь, пустое чтение или сжатую загрузку. Проверьте файл, который вы загрузили. Пустой список $signatures — это другое: файл является PDF, но не несёт словаря /Type /Sig, поэтому проверять нечего.

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

Заголовок раздела «LtvException: Strict revocation: LTV warning: no revocation data for certificate at chain position 0»

enableLtv() не смог получить ответ OCSP или CRL для сертификата цепочки, и строгое значение по умолчанию отказывается записывать заявку B-LT без доказательств. Проверьте доступность респондера с хоста или передайте enforcementMode: RevocationEnforcementMode::PERMISSIVE только если вы явно принимаете запуск только с предупреждениями — никогда не помечайте такой вывод как B-LT для производственных или комплаенс-процессов, если отсутствие доказательств об отзыве не принято и не задокументировано явно. Связанное: запрос B-LTA без TSA-клиента завершается ошибкой LtvException: TSA client required for document timestamps.