Проверка подписи: криптографическая проверка AdES / PAdES
NextPDF Enterprise криптографически проверяет цифровые подписи. Сторона проверки читает Cryptographic Message Syntax (CMS) SignedData или токен метки времени Request for Comments (RFC) 3161 из PDF, заново вычисляет дайджесты, проверяет подписи, связывает каждую подпись с её сертификатом подписания и проверяет цепочку сертификатов, включая обработку политик сертификатов, относительно хранилища якорей доверия, предоставленного вызывающей стороной. На этой странице описано поведение: что проверяется, что отклоняется по принципу fail-closed, какие алгоритмы поддерживаются и где проходит граница доверия.
Это отличается от Validation, где выполняются только структурные проверки политик в режиме чтения и намеренно не выполняется никакая криптография. Это также аналог на стороне проверки для производителя подписей, который записывает структуры PDF Advanced Electronic Signatures (PAdES) B-LT / B-LTA.
Установка
Заголовок раздела «Установка»composer require nextpdf/enterprise:^3Концептуальный обзор
Заголовок раздела «Концептуальный обзор»Проверка опирается на доказательства и работает по принципу fail-closed: проверка, которую нельзя положительно установить, не даёт положительного результата. Перечисленные ниже элементы складываются в единый итог, который несёт ValidationReport.
Криптографическая проверка CMS / токена метки времени. Автономный строгий DER-стек с определённой длиной разбирает CMS SignedData и токен метки времени RFC 3161. Токен принимается только тогда, когда содержит ровно один SignerInfo, его подписанные атрибуты строго разобраны, сертификат подписавшего разрешён, атрибут message-digest совпадает с заново вычисленным дайджестом, обязательная привязка к сертификату подписания (ESS signing-certificate-v2) выполнена, а подпись SignerInfo проверяется по подписанным атрибутам после повторного DER-кодирования. Правило сопоставления дайджестов следует модели проверки RFC 5652 §5.6 / §5.4: получатель заново вычисляет дайджест содержимого, и подпись действительна только тогда, когда это значение равно подписанному атрибуту messageDigest. Верификатор никогда не доверяет дайджесту, предоставленному производителем.
Проверка сертификата TSA на момент genTime. genTime метки времени — это момент UTC, когда токен был создан (RFC 3161 §2.4.2). Сертификат подписания TSA проверяется именно на этот момент, а не на “сейчас”: его расширенное использование ключа должно быть единственным критическим id-kp-timeStamping (RFC 3161 §2.3), а окно действия, цепочка, происхождение якоря доверия и статус отзыва оцениваются относительно genTime. Структурно правильная цепочка, которая не доходит до настроенного якоря доверия, никогда не может обосновать положительный результат.
Отсоединённые базовые подписи документов PAdES. Специализированный экстрактор выполняет полноценную базовую проверку Advanced Electronic Signatures (AdES) / PAdES для отсоединённой подписи документа: дайджест сообщения заново вычисляется по подписанному диапазону байтов и сравнивается, подпись проверяется, а привязка к сертификату подписания обязательна. Это заменяет прежний резервный вариант, основанный только на структуре. Верификатор меток времени и экстрактор подписей документов используют общий валидатор ESS issuer-and-serial, поэтому разбор привязки к сертификату не расходится.
Архивная цепочка покрытия DocTimeStamp. validateArchivalTimestampChain() проверяет цепочку доверенных токенов DocTimeStamp по диапазонам байтов PDF как архивное доказательство B-LTA. Отпечаток каждого токена привязан к фактическим байтам ByteRange, которые он покрывает, цепочка соблюдает строгий порядок ETSI, цепочка TSA каждого токена привязана к якорю доверия, и цепочка должна покрывать файл до его маркера конца файла. Полностью пройденный результат возможен только для полной, привязанной к якорю доверия цепочки, покрывающей файл до EOF.
Обработка политик сертификатов (RFC 5280 §6.1.4). Проверка пути применяет полную обработку политик сертификатов: дерево узлов политик, сопоставление политик с резервным вариантом anyPolicy и свёртку policyConstraints / inhibitAnyPolicy, опираясь на DER-читатель расширений политик с поведением fail-closed. Переменные состояния обработки пути explicit_policy и inhibit_anyPolicy (RFC 5280 §6.1.2) определяют, требуется ли непустое дерево действительных политик; завершающий шаг пересекает дерево действительных политик с user-initial-policy-set (RFC 5280 §6.1.4). Без обязательных политик и при принятом anyPolicy обработка не ограничена; это поведение по умолчанию не изменилось.
Поддерживаемые алгоритмы
Заголовок раздела «Поддерживаемые алгоритмы»Сторона проверки принимает приведённый ниже набор алгоритмов и отклоняет по принципу fail-closed всё, что в него не входит: неподдерживаемый алгоритм означает отклонённую проверку, а не тихий пропуск.
| Семейство | Поддержка | Примечания |
|---|---|---|
| RSA (PKCS#1 v1.5) — схема подписи | rsaEncryption с SHA-2 и sha*WithRSAEncryption (OID) | Принимается |
| ECDSA | кривые P-256, P-384, P-521 | Принимается |
| RSASSA-PSS (схема подписи) | — | Не поддерживается → fail-closed |
| EdDSA (схема подписи) | — | Не поддерживается → fail-closed |
| Дайджесты SHA-3 | — | Не поддерживается → fail-closed |
| SHA-1 | — | Слабый алгоритм: базовая подпись, проверяемая под SHA-1, понижается до сбоя по криптографическим ограничениям, а не до прохождения |
Программный интерфейс
Заголовок раздела «Программный интерфейс»Сторону проверки используют через публичный движок и контракты Core / Pki. Конкретные классы стратегий внутренние.
| Тип | Вид | Роль |
|---|---|---|
AdESValidationEngine | класс | Точка входа на стороне проверки: проверка подписи и архивной цепочки. |
AdESValidationEngine::validateArchivalTimestampChain() | метод | Проверить доверенную цепочку покрытия DocTimeStamp по диапазонам байтов PDF. |
ValidationReport | результат | Структурированный итог: общий статус плюс выводы по каждой проверке. |
PathValidatorInterface | интерфейс (NextPDF\…\Pki) | SPI проверки пути сертификации, от которого зависит движок. |
PathValidationOptions | объект-значение | Параметры управления обработкой политик: requireExplicitPolicy, inhibitAnyPolicy, inhibitPolicyMapping, maxPolicyFanout. |
TrustAnchorStoreInterface | интерфейс | Предоставленный вызывающей стороной набор доверенных якорей, относительно которого оценивается цепочка. |
У метода проверки архивной цепочки такая сигнатура:
public function validateArchivalTimestampChain( string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null,): ValidationReport;Метод возвращает полностью пройденный результат только тогда, когда цепочка DocTimeStamp полностью проверена, привязана к якорю доверия и покрывает файл до его маркера EOF.
CertificateChainValidator::validate() принимает набор начальных политик (user-initial-policy-set из RFC 5280). По умолчанию это anyPolicy; он не накладывает ограничений, поэтому обычная цепочка не затрагивается. Передайте явный набор или установите requireExplicitPolicy, чтобы потребовать непустое дерево действительных политик.
Пример кода — быстрый старт
Заголовок раздела «Пример кода — быстрый старт»use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
$report = $engine->validateArchivalTimestampChain($pdfBytes, [], $trustAnchors);
if ($report->isTotalPassed()) { // A complete, trust-anchored, EOF-covering DocTimeStamp chain.}Пример кода — продакшн
Заголовок раздела «Пример кода — продакшн»use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;use Psr\Log\LoggerInterface;
final readonly class ArchivalEvidenceCheck{ public function __construct( private AdESValidationEngine $engine, private LoggerInterface $logger, ) {}
public function check(string $pdfBytes, TrustAnchorStoreInterface $anchors): bool { $report = $this->engine->validateArchivalTimestampChain($pdfBytes, [], $anchors);
foreach ($report->findings as $finding) { $this->logger->info('archival.finding', [ 'check' => $finding->checkId, 'status' => $finding->status->value, ]); }
// A positive result proves byte-range coverage by a trusted timestamp // chain — it is one input to your decision, not a legal conclusion. return $report->isTotalPassed(); }}Изменения поведения и заметки по обновлению
Заголовок раздела «Изменения поведения и заметки по обновлению»Сторона проверки перешла от приёма по структуре / времени к полной криптографической проверке. Если вы полагаетесь на прежнее, более мягкое поведение, учтите эти изменения.
- Fail-closed для распознаваемой, но непроверяемой метки времени. Токен DocTimeStamp или архивный токен, который ранее проходил по структурным и временным признакам, теперь требует полной криптографической проверки: подписи, message-digest и привязки к сертификату подписания. Токен, который не проходит проверку, больше не даёт положительного доказательства существования; его результат становится неопределённым или неуспешным.
- Базовые подписи SHA-1 понижаются, а не проходят. Базовая подпись документа, которая проверяется, но использует SHA-1, сообщается как сбой по криптографическим ограничениям, а не как полное прохождение.
- Обработка политик сертификатов RFC 5280 §6.1.4 применяется в обязательном порядке. Цепочка, у которой
explicit_policyдостигает нуля при пустом дереве действительных политик, теперь не проходит, в том числе если это вызваноpolicyConstraintsrequireExplicitPolicyвнутри цепочки. Цепочки по умолчанию, без ограничений (без обязательных политик, с принятымanyPolicy) не затрагиваются. - Изменение сигнатуры конструктора (нарушение обратной совместимости).
AdESValidationEngine::__construct()теперь объявляет параметр$chainValidatorкак SPIPki\PathValidatorInterface, со значением по умолчанию, которое лениво устанавливается вPki\CertificateChainValidator::withDefaults(). Ранее это был конкретныйLtv\CertificateChainValidator. Вызывающая сторона, которая внедряла конкретный валидатор LTV, должна вместо этого внедрить реализацию SPI Pki. Валидатор Pki оборачивает тот же структурный движок пути и добавляет ограничения имён и обработку политик; для входных данных, соответствующих настройкам по умолчанию, он не меняет поведение.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Неподдерживаемый алгоритм ≠ неопределённость. RSASSA-PSS, EdDSA и SHA-3 отклоняются по принципу fail-closed, а не переводятся в неопределённое состояние. Если ваши подписанты используют их, эта сторона проверки не вернёт положительный результат.
- Доверие относительно якоря. Проверка всегда относительна к хранилищу якорей доверия, которое вы предоставляете. Пустой или неправильный набор якорей даёт результат “не доверено” независимо от криптографической корректности.
- genTime, а не сейчас. Сертификат TSA оценивается на момент
genTimeтокена. Сертификат TSA, который с тех пор истёк, всё ещё может обосновать токен, созданный, пока он был действителен; сертификат, ещё не действительный на моментgenTime, — не может. - Покрытие до EOF. Архивная цепочка должна покрывать документ до его маркера EOF. Метка времени, покрывающая лишь префикс файла, не устанавливает покрытие всего документа.
- “Не доказано отозванным” — это не Good. Вердикт
Validтребует достоверно неотозванного статуса. Если и OCSP, и CRL возвращают Unknown или Unavailable, даже криптографически корректная подпись с проверенной цепочкой и якорем доверия разрешается вIndeterminate. Предоставьте встроенный материал OCSP/CRL со статусом Good для сертификата подписавшего, чтобы достичьValid.
Производительность
Заголовок раздела «Производительность»Проверка выполняется внутри процесса по предоставленным байтам PDF и встроенному материалу проверки; стоимость растёт с длиной цепочки и числом меток времени. Проверка не делает сетевых обращений. Материал для проверки отзыва и доверия берётся из данных, которые предоставляет вызывающая сторона или которые встроены в документ. Проверка детерминирована: одни и те же входные данные и одни и те же якоря доверия дают один и тот же отчёт.
Примечания по безопасности
Заголовок раздела «Примечания по безопасности»- Fail-closed — это поведение по умолчанию. Каждый шаг приёма отклоняет материал, который не может положительно проверить. Это не позволяет документу заявлять действительность, которую движок никогда не устанавливал.
- Дописывание после метки времени отражается покрытием до EOF. Поскольку отпечаток каждой архивной метки времени привязан к фактическим байтам
ByteRangeи цепочка должна доходить до EOF, содержимое, дописанное после метки времени, не покрывается ею и не получает её доказательственного веса. - Считайте входные данные враждебными. Байты PDF, встроенный CMS и токены меток времени из недоверенных источников разбираются строгим DER-читателем с определённой длиной, который отклоняет некорректные кодировки и кодировки неопределённой длины.
Резидентность данных и меры по защите PII
Заголовок раздела «Резидентность данных и меры по защите PII»Проверка выполняется внутри процесса и локально, без сетевого ввода-вывода. Сертификаты и подписи несут идентификационные данные субъекта; применяйте собственные средства контроля хранения и минимизации к отчётам и любым извлечённым данным сертификатов.
Безопасная телеметрия и очистка журналов
Заголовок раздела «Безопасная телеметрия и очистка журналов»Выводы содержат идентификаторы и статусы проверок. Некоторые диагностические данные могут включать имена субъектов сертификатов или серийные номера; очищайте или скрывайте эти поля, прежде чем пересылать журналы в общие приёмники.
Границы области применения
Заголовок раздела «Границы области применения»Указывайте эти границы в выводе для пользователя, чтобы положительный результат не трактовался слишком широко.
validateArchivalTimestampChain()доказывает покрытие диапазона байтов, а не достижимость по xref. Он устанавливает, что доверенная цепочка меток времени криптографически покрывает диапазоны байтов документа до EOF. Он не выполняет анализ на уровне xref или анализ достижимости объектовstartxref; это намеренно вне области применения. Правило покрытия до EOF вместе с привязкой к якорю доверия учитывает атаки дописывания после метки времени, а не анализ графа объектов.- Намеренно вне области применения. Записи доказательств (RFC 4998 / RFC 6283); проверка токенов меток времени RSASSA-PSS, EdDSA или SHA-3; интеграция с доверенными списками (TSL) и квалифицированными TSA; а также онлайн-получение информации об отзыве TSA этой стороной проверки не предоставляются. Отзыв оценивается по материалу, уже доступному верификатору.
Соответствие
Заголовок раздела «Соответствие»| Поведение | Ссылка | Статус |
|---|---|---|
Значение подписи / токен метки времени хранятся в кодировке DER в /Contents | ISO 32000-2 §12.8.1 | Разобрано и проверено |
| Словарь метки времени документа | ISO 32000-2 §12.8.5 | Читается для архивной цепочки |
| Получатель заново вычисляет дайджест содержимого; он должен быть равен атрибуту messageDigest | RFC 5652 §5.6 / §5.4 | Применяется |
Сертификат TSA несёт единственный критический id-kp-timeStamping (EKU) | RFC 3161 §2.3 | Проверяется на момент genTime |
| genTime — это момент создания по UTC | RFC 3161 §2.4.2 | Используется как момент проверки |
Переменные состояния обработки политик (explicit_policy, inhibit_anyPolicy) | RFC 5280 §6.1.2 | Обрабатывается |
| Завершающий шаг пересекает дерево действительных политик с user-initial-policy-set | RFC 5280 §6.1.4 | Применяется |
| Записи DSS и метки времени документа для долгосрочных подписей | ETSI EN 319 142-2 §5.5 | Проверяется как архивное доказательство |
Все пункты приведены в пересказе. NextPDF не воспроизводит нормативный текст; за авторитетной формулировкой обращайтесь к опубликованным стандартам. NextPDF не делает заявления о сертификации AdES / PAdES. Сторона проверки реализует криптографические проверки, описанные цитируемыми спецификациями; это не сертифицированная служба проверки, и она не выдаёт стороннего удостоверения.
Поведение в режиме FIPS
Заголовок раздела «Поведение в режиме FIPS»Когда активен профиль Enterprise FIPS, ограничения применяются к алгоритмам дайджеста и подписи, которые принимает верификатор. Логика проверки, включая повторное вычисление дайджеста, проверку подписи, привязку к сертификату и проверку пути, не изменяется.
Модель угроз
Заголовок раздела «Модель угроз»| Актив | Противник | Риск | Меры защиты |
|---|---|---|---|
| Токен метки времени | Поддельный или изменённый токен | Ложное доказательство существования | Полная криптографическая проверка; fail-closed для всего непроверяемого |
| Сертификат TSA | Недоверенный издатель | Мнимое доверие, которое верификатор не должен утверждать | Цепочка проверена до предоставленного вызывающей стороной якоря на момент genTime; недоверенная цепочка никогда не проходит |
| Байты документа | Дописывание после метки времени | Содержимое получает вес метки времени без покрытия | Отпечаток привязан к фактическим байтам ByteRange + правило покрытия до EOF |
| Слабый алгоритм | Понижение до SHA-1 / неподдерживаемой схемы | Слабая подпись, распознанная как действительная | SHA-1 понижается; RSASSA-PSS / EdDSA / SHA-3 fail-closed |
Ограничение по редакции
Заголовок раздела «Ограничение по редакции»Эта сторона проверки — функция Enterprise и поставляется в пакете nextpdf/enterprise. NextPDF Core обнаруживает наличие подписи и создаёт подписи B-B / B-T, но не предоставляет эту криптографическую сторону проверки. Получить лицензию.
Флаг возможности лицензии
Заголовок раздела «Флаг возможности лицензии»Сторона проверки ограничена редакцией Enterprise (license_feature_flag: enterprise). Она разрешается через контракты Core и Pki; публичный API приложения не меняется при обновлении редакции.
Контракт поведения
Заголовок раздела «Контракт поведения»- Токен CMS или метки времени принимается только при наличии ровно одного
SignerInfo, строго разобранных подписанных атрибутов, разрешённого сертификата подписавшего, совпадающего message-digest, обязательной привязки к сертификату подписания и проверяемой подписиSignerInfo. - Сертификат TSA проверяется на момент
genTimeтокена: единственный критический EKUid-kp-timeStamping, окно действия, привязанная к якорю доверия цепочка и статус отзыва. - Вердикт
Validдополнительно требует достоверно неотозванного статуса: по крайней мере одного авторитетного Good (проверенного ответа OCSP со статусом Good или свежего CRL, помещающего серийный номер вне неистёкшего списка). Статус, который лишь “не доказано отозванным”, когда и OCSP, и CRL являются Unknown или Unavailable, разрешается вIndeterminate, но никогда вValid(ETSI EN 319 102-1: revocation status-unavailable → INDETERMINATE). Поскольку резервный путь CRL удостоверяет только свежесть списка, а не неотозванность конкретного серийного номера, цепочка только с CRL без Good OCSP обычно бываетIndeterminate. validateArchivalTimestampChain()возвращает полностью пройденный результат только для полной, привязанной к якорю доверия цепочки DocTimeStamp, покрывающей файл до EOF; он доказывает покрытие диапазона байтов, а не достижимость по xref.- Обработка политик сертификатов следует RFC 5280 §6.1.4; цепочки по умолчанию, без ограничений, не затрагиваются.
- Поддерживаемые алгоритмы — RSA (PKCS#1 v1.5 с SHA-2) и ECDSA (P-256/384/521); RSASSA-PSS, EdDSA и SHA-3 отклоняются по принципу fail-closed; SHA-1 понижается.
Статус сканирования на NDA
Заголовок раздела «Статус сканирования на NDA»Эта публичная страница описывает только внешне наблюдаемое поведение стороны проверки. Она называет публичный движок, контракты Pki / якорей доверия и метод validateArchivalTimestampChain() через поддерживаемый интерфейс. Конкретные внутренние компоненты DER, CMS, обработчика политик и валидатора пути находятся в закрытом справочном разделе под соглашением о неразглашении (NDA).
Резервный вариант Core
Заголовок раздела «Резервный вариант Core»NextPDF Core обнаруживает наличие подписи и создаёт подписи B-B / B-T, но не проверяет криптографически токены CMS или меток времени, не проверяет архивную цепочку и не выполняет обработку политик RFC 5280 §6.1.4. Развёртывание только с Core не имеет эквивалентной стороны проверки; см. Security / Signing (Core).
Резервный вариант Pro
Заголовок раздела «Резервный вариант Pro»NextPDF Pro добавляет стратегии подписания и обработку электронных счетов, но не предоставляет эту криптографическую сторону проверки; проверка архивной цепочки и обработка политик сертификатов поставляются только в nextpdf/enterprise.
Примечание о границе Enterprise
Заголовок раздела «Примечание о границе Enterprise»Сторона проверки описана на уровне поведения. Строгий стек DER, парсер CMS, обработчик политик и внутренние компоненты валидатора пути находятся вне области публичного интерфейса и здесь не воспроизводятся.
Граница развёртывания
Заголовок раздела «Граница развёртывания»Проверка зависит от хранилища якорей доверия и любого материала об отзыве, который предоставляет вызывающая сторона или который встроен в документ. NextPDF Enterprise оценивает этот материал; он не управляет списком доверия, TSA или службой отзыва. Оператор отвечает за выбор якорей и свежесть встроенного материала об отзыве.
Граница юридического соответствия
Заголовок раздела «Граница юридического соответствия»Эта страница помечена export_control_class: legal-review-required; она касается криптографической проверки. Юридическое одобрение требуется до установки флага publish. Положительный результат проверки — это криптографическое утверждение о подписях и метках времени документа. Это не юридическое заключение, не определение квалифицированного статуса eIDAS и не сертификация. NextPDF не делает заявления о сертификации AdES / PAdES. Обращайтесь к собственным консультантам по соответствию и юристам по вопросам ваших регуляторных обязательств.
См. также
Заголовок раздела «См. также»- Signature: производитель PAdES B-LT / B-LTA — сторона производителя.
- Validation — структурные проверки политик, выполняемые внутри процесса (без криптографии).
- Archive: DSS, VRI, состояние LTV — долгосрочное архивирование и состояние LTV.
- Security / Signing (Core) — CMS, RFC 3161, проверка пути RFC 5280, OCSP/CRL.
- Сопоставление базовых уровней PAdES — B-B, B-T, B-LT, B-LTA по редакциям.
- PAdES · DSS · LTV — термины глоссария.