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

Enterprise редакция

Проверка подписи — глубокий справочник

Эта страница — подробный справочник по поверхности проверки AdES в NextPDF Enterprise. Точка входа — NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Он реализует смоделированные по ETSI процессы проверки NextPDF для базовых, временных, долгосрочных и архивных проверок меток времени: базовая проверка, проверка со временем, проверка с долгосрочными данными и проверка архивной цепочки покрытия DocTimeStamp. Результаты — значения ValidationReport, несущие варианты перечислений MainIndication и SubIndication со строковыми значениями URN ETSI. Дополнительные поверхности, описанные здесь: SPI SignatureDataExtractor и его реализация CmsSignatureDataExtractor, побайтовый сканер PdfSignatureDictionaryScanner, поверхность проверки пути NextPDF\Enterprise\Security\Pki и BatchSignatureValidator. Руководство на уровне рабочих процессов см. в Проверка подписи: криптографическая сторона проверки AdES / PAdES.

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

СимволПараметрыПоведение по умолчаниюВозвращаетВыбрасывает или завершается сПримечания
AdESValidationEngine::__construct11 необязательных параметров: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy и пять необязательных верификаторов-коллабораторовВсе значения по умолчанию fail-closed: валидатор пути Pki поверх часов движка, без извлекателя, без хранилища доверия TSAНовый движокНе выбрасываетБез хранилища доверия оценка цепочки TSA сообщает о недоверии; это отображается в INDETERMINATE, никогда в прохождение
AdESValidationEngine::validateBasicstring $signedData, string $signatureБазовая проверка: формат, дайджест, крипто, слабый алгоритм, цепочка, отзыв с учётом происхожденияValidationReportНе выбрасывает; ошибки извлечения и пути отображаются в отчёты fail-closedБез извлекателя — только защитные проверки; см. крайние случаи
AdESValidationEngine::validateWithTimestring $signedData, string $signature, DateTimeImmutable $claimedTimeСначала базовая проверка; окно сертификата и отзыв сравниваются с заявленным временемValidationReportНе выбрасываетСтрогий контроль метки времени подписи при наличии атрибута; $claimedTime остаётся временным якорем
AdESValidationEngine::validateWithLongTermDatastring $signedData, string $signature, array $dssData (certs/ocsps/crls)Требуется прохождение базовой проверки; контроль метки времени подписи с проверкой TSA на genTime; контроли POE, отзыва DSS и архивныеValidationReportНе выбрасываетNetworkPolicy::STRICT_OFFLINE при недостатке встроенных данных даёт INDETERMINATE / TRY_LATER
AdESValidationEngine::validateArchivalTimestampChainstring $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = nullОснованная на доказательствах цепочка покрытия DocTimeStamp по точным байтам ByteRangeValidationReportНе выбрасывает на враждебных байтахTOTAL_PASSED только для доверенной цепочки, покрывающей до EOF
MainIndicationПеречисление на строках, три вариантаЗначения URN ETSI; см. список вариантов ниже
SubIndicationПеречисление на строках, пятнадцать вариантовЗначения URN ETSI; см. список вариантов ниже
ValidationReport::__constructMainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = ''Неизменяемый (final readonly) результат проверкиНовый отчётНе выбрасываетisPassed(), isFailed(), isIndeterminate(), toArray()
DiagnosticData::__constructarray $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (все со значениями по умолчанию)Неизменяемый контейнер доказательств; только для журнала аудитаНовое значениеНе выбрасываетtoArray() сериализует ссылки для отчётности
SignatureDataExtractor::extractstring $signedData, string $signatureSPI: разобрать CMS и извлечь компоненты проверкиExtractedSignatureDataSignatureExtractionException, когда подпись не удаётся разобратьИнтерфейс; отделяет разбор ASN.1 от движка
CmsSignatureDataExtractor::extractstring $signedData, string $signatureИзвлечение плюс криптографическая проверка отделённой базовой подписи PAdESExtractedSignatureDataSignatureExtractionException только когда CMS вообще не удаётся разобратьОшибка крипто или привязки возвращает данные с cryptoValid / hashValid равными false; для этого исключение никогда не выбрасывается
PdfSignatureDictionaryScanner::scanstring $pdfBytesПобайтовое сканирование словарей /ByteRange + /Contents с точными перекрёстными антиподменными проверкамиlist<PdfSignatureOccurrence>Тотальная; никогда не выбрасывает; некорректные кандидаты пропускаютсяУпорядочено по концу покрытия, сначала самые ранние
PathValidatorInterface::validatearray $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = []Проверка пути по RFC 5280 §6.1.4 с обработкой политикPathValidationResultPathValidationException при структурно недопустимой цепочке или превышении враждебного лимитаЦепочка: сначала конечный субъект, якорь последним
PathValidatorInterface::validateWithAiaChasingarray $chain, ?DateTimeImmutable $validationTime = nullРазрешение через AIA недостающих промежуточных сертификатов, затем проверкаPathValidationResultPathValidationExceptionЗагрузки ограничены таймаутом и лимитами байтов
CertificateChainValidatorКонструктор: движок, PathValidationOptions, часы, логгер; статический withDefaults()Реализация SPI с враждебными лимитами по умолчаниюPathValidationResult из обоих методовPathValidationExceptionТакже выбрасывается, когда OpenSSLCertificate не удаётся экспортировать в PEM
PathValidationOptions::__constructЛимиты (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) плюс флаги политик, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchorГлубина 32, разветвление 64, 5 с на загрузку, 10 MiB на загрузку; все флаги falseНовые параметрыНе выбрасываетФабрики: defaults(), strict(), withTrustAnchors()
PathValidationResult::__constructbool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasonsНеизменяемый результат; trustAnchorTrusted по умолчанию false (fail-closed)Новое значениеНе выбрасываетЧленство в доверии отличается от структурной валидности
PolicyProcessorКонструктор: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree()Расширение, отображение и завершение дерева политик по RFC 5280 §6.1.4void / list<non-empty-string> / PolicyTreePathValidationException при любой ошибке обработки политик (fail-closed)Завершение возвращает уцелевшие OID политик, исключая anyPolicy
PolicyTreeattach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), плюс запросы на чтениеСостояние valid_policy_tree с индексом глубиныЗависит от методаPathValidationException, когда число живых листьев превышает лимит разветвленияПредоставляет ANY_POLICY_OID (2.5.29.32.0)
NameConstraintsChecker::processCertificatestring $certDer, bool $applyNameCheckНакапливает и применяет разрешённые / исключённые поддеревья согласно RFC 5280 §6.1.4(g)voidPathValidationException при нарушении поддерева, неподдерживаемой форме GeneralName в ограничении или превышении лимитаНесравнимые имена обрабатываются по принципу fail-closed
TrustAnchorStoreInterface::containsFingerprintstring $anchorDerSha256HexЧленство по SHA-256 в нижнем регистре hex над DER-сертификатом якоряboolНе выбрасываетШов доверия, к которому обращается валидатор пути
BatchSignatureValidator::validatearray $inputs (list<DocumentSignatureInput>)Проверка подписей нескольких документов с кэшированием отзыва в пределах пакетаBatchValidationReportInvalidArgumentException при пустом списке; ресурсный ограничитель отклоняет пакеты свыше 1000 документовНаходится в NextPDF\Enterprise\Signature
final class AdESValidationEngine
public function validateBasic(string $signedData, string $signature): ValidationReport
public function validateWithTime(
string $signedData,
string $signature,
DateTimeImmutable $claimedTime,
): ValidationReport
public function validateWithLongTermData(
string $signedData,
string $signature,
array $dssData,
): ValidationReport
public function validateArchivalTimestampChain(
string $pdfBytes,
array $dssData = [],
?TrustAnchorStoreInterface $anchors = null,
): ValidationReport
public function validate(
array $chain,
?DateTimeImmutable $validationTime = null,
array $initialPolicies = [],
): PathValidationResult;
public function validateWithAiaChasing(
array $chain,
?DateTimeImmutable $validationTime = null,
): PathValidationResult;
public static function withDefaults(
?ClockInterface $clock = null,
?AiaChaser $aiaChaser = null,
?LoggerInterface $logger = null,
): self
public function containsFingerprint(string $anchorDerSha256Hex): bool;
public function extract(string $signedData, string $signature): ExtractedSignatureData;
public function scan(string $pdfBytes): array
public function validate(array $inputs): BatchValidationReport

Перечисления индикаций. Варианты MainIndication: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. Базовые значения следуют шаблону urn:etsi:019102:mainindication:total-passed (нижний регистр, через дефис). Варианты SubIndication: HASH_FAILURE, SIG_CRYPTO_FAILURE, REVOKED, EXPIRED, NOT_YET_VALID, NO_POE, TRY_LATER, CERTIFICATE_CHAIN_GENERAL_FAILURE, FORMAT_FAILURE, REVOKED_CA_NO_POE, CRYPTO_CONSTRAINTS_FAILURE, POLICY_PROCESSING_FAILURE, REVOCATION_OUT_OF_BOUNDS_NO_POE, NO_SIGNING_CERTIFICATE_FOUND, TIMESTAMP_ORDER_FAILURE. Каждый подкреплён urn:etsi:019102:subindication:<CASE_NAME> с точным именем варианта.

  • Отчёты на входе, отчёты на выходе. Четыре точки входа движка возвращают ValidationReport для враждебного ввода вместо выбрасывания исключения. Перехваченное SignatureExtractionException направляется на защитный путь; перехваченное PathValidationException отображается в TOTAL_FAILED / CERTIFICATE_CHAIN_GENERAL_FAILURE.
  • Порядок базовой проверки. Сначала проверка формата; неразбираемая структура — это TOTAL_FAILED / FORMAT_FAILURE (EN 319 102-1 §5.3.4). Затем дайджест (HASH_FAILURE) и криптографическая проверка (SIG_CRYPTO_FAILURE), что соответствует результатам строительного блока EN 319 102-1 §5.2.7.4. Дайджест пересчитывается верификатором и сравнивается с подписанным атрибутом messageDigest (RFC 5652 §5.6); дайджесты, предоставленные производителем, никогда не считаются доверенными.
  • Слабые алгоритмы понижают результат. Подпись, проходящая проверку под SHA-1 или со слабой привязкой сертификата подписи, возвращает INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE, никогда TOTAL_PASSED. Временной путь подтверждает это повторно, так что слабая подпись никогда не отмывается в проходной результат, действительный по времени.
  • Контроль происхождения отзыва. Флаги отзыва извлекателя учитываются только тогда, когда извлекатель действительно выполнил проверку отзыва (revocationChecked равно true). Непроверенное значение по умолчанию — это ни “подтверждено, что не отозвано”, ни триггер REVOKED. Доказательство отзыва устанавливается путём DSS.
  • Распространение непрохождения. Временной и долгосрочный пути никогда не повышают непроходной базовый результат. Существует одно исключение: базовый INDETERMINATE / REVOKED разрешается относительно $claimedTime; отзыв в момент заявленного времени или ранее — это TOTAL_FAILED / REVOKED. Это отражает шаблон EN 319 102-1 §5.3.4 по разрешению связанной с отзывом неопределённости с помощью временного доказательства. Когда сравнение выполнить невозможно, неразрешённый базовый отчёт распространяется дословно.
  • Строгая привязка метки времени подписи (fail-closed; нарушение обратной совместимости). Когда CMS несёт неподписанный атрибут id-aa-timeStampToken, его наличие запускает принудительную проверку и на временном, и на долгосрочном пути; режима “только предупреждение” нет. Кардинальность должна быть ровно один атрибут ровно с одним значением (EN 319 122-1 §5.3); любая иная форма — это TOTAL_FAILED / FORMAT_FAILURE. Токен должен пройти криптографическую проверку от начала до конца; непроверяемый токен, конфликт различий парсеров или несовпадение отпечатка — это INDETERMINATE / TIMESTAMP_ORDER_FAILURE. Неподдерживаемый или SHA-1 алгоритм отпечатка — это INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE. Правило привязки — RFC 3161 Appendix A: messageImprint токена должен быть равен хешу октетов значения signature из SignerInfo, сравниваемому за постоянное время.
  • Контроли долгосрочного пути. На пути, аннотированном пунктом 5.4, привязанная метка времени подписи дополнительно проходит оценку сертификата TSA на момент genTime токена; недоверенный якорь — это INDETERMINATE / CERTIFICATE_CHAIN_GENERAL_FAILURE, никогда прохождение. NetworkPolicy::STRICT_OFFLINE при недостаточном встроенном материале DSS возвращает INDETERMINATE / TRY_LATER. Доказательство существования, отзыв DSS и находки по архивной цепочке каждый раз замыкают на INDETERMINATE с сопоставленной субиндикацией.
  • Контроли архивной цепочки. Отсутствие DocTimeStamp — это INDETERMINATE / NO_POE. Структурно несоответствующий ByteRange — это TOTAL_FAILED / FORMAT_FAILURE. Каждый токен должен пройти проверку, привязать свой отпечаток к точным байтам, покрытым ByteRange, и пройти сопоставление аспектов TSA на genTime (EXPIRED, NOT_YET_VALID, REVOKED_CA_NO_POE, CERTIFICATE_CHAIN_GENERAL_FAILURE или TRY_LATER в строгом офлайн-режиме). Порядок применяется принудительно: неубывающий genTime, строго прогрессирующее покрытие и то, что более поздние токены содержат дырку /Contents предыдущего токена. Самый поздний токен должен покрывать финальный байт; замыкающие байты — это TIMESTAMP_ORDER_FAILURE. genTime, опережающий часы верификатора более чем на 300 секунд, — это TIMESTAMP_ORDER_FAILURE.
  • Диагностика никогда не решает. Записи доказательства существования в DiagnosticData::$timestamps предназначены только для журнала аудита. Они никогда не меняют индикацию, и накопитель сбрасывается на каждой точке входа.
  • Лимиты Pki предшествуют крипто. Лимиты PathValidationOptions (глубина 32, разветвление политик 64, 5 с и 10 MiB на загрузку) проверяются до затратной работы. PathValidationResult::$trustAnchorTrusted отличается от $valid; requireTrustedAnchor делает неподтверждённую конечную точку недействительной. strict() включает requireExplicitPolicy, жёсткий отказ при транспорте отзыва и requireTrustedAnchor. Действительность пути определяется относительно якоря согласно RFC 5280 §6.1: действительный путь начинается с якоря доверия, предоставленного на входе.
  • Пакетная поверхность. BatchSignatureValidator::validate() выбрасывает InvalidArgumentException для пустого списка и отклоняет пакеты свыше 1000 документов через ресурсный ограничитель. PHP владеет всей криптографической проверкой в этом конвейере.
  • Движок по умолчанию не имеет извлекателя. new AdESValidationEngine() выполняет только защитные проверки: пустая подпись или подписанные данные — это TOTAL_FAILED; любая непустая пара разрешается в INDETERMINATE / NO_SIGNING_CERTIFICATE_FOUND, никогда TOTAL_PASSED. Внедрите NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor, чтобы получить криптографическую проверку.
  • Проверка доверия TSA по умолчанию не имеет хранилища. Тогда каждая цепочка TSA сообщает о недоверии, поэтому архивные и долгосрочные результаты метки времени подписи остаются INDETERMINATE. Предоставьте якоря через validateArchivalTimestampChain(..., $anchors) или настроенный TsaCertificateAtGenTimeCheck.
  • Пустые $pdfBytes. validateArchivalTimestampChain('') возвращает TOTAL_FAILED / FORMAT_FAILURE.
  • Метки времени подписи до исправления не могут пройти. Токены, созданные версиями NextPDF до исправления строгой привязки, отпечатывали другой ввод. Они навсегда не проходят привязку Appendix A; повторно подпишите и заново проставьте метку времени, чтобы восстановить положительный результат. Это преднамеренное, задокументированное нарушение обратной совместимости.
  • Дублирующиеся или перекрывающиеся DocTimeStamp. Дубликат в той же ревизии, равное или перекрывающееся покрытие либо более поздний токен, не содержащий дырку подписи предыдущего токена, не проходит контроль порядка.
  • Сканер тотальный и побайтовый. scan() молча пропускает некорректных или подменных кандидатов; ложный /ByteRange внутри потока содержимого отклоняется. Он не разрешает косвенные объекты и не обходит таблицу перекрёстных ссылок.
  • Покрытие, а не достижимость. validateArchivalTimestampChain() доказывает криптографическое покрытие диапазона байтов до конца файла. Анализ достижимости на уровне объектов (например, перенаправленный корень документа внутри покрытой ревизии) объявлен вне области действия.
  • Прямое использование Pki выбрасывает исключение. Прямой вызов реализаций PathValidatorInterface порождает PathValidationException для структурно недопустимых цепочек, превышенных лимитов, неподдерживаемых форм ограничений и неудавшегося экспорта в PEM дескриптора OpenSSLCertificate. Движок перехватывает этот класс; ваши собственные вызывающие стороны должны его обрабатывать.

Сторона проверки принимает RSA PKCS#1 v1.5 с SHA-2 и ECDSA на P-256/P-384/P-521. Токены RSASSA-PSS, EdDSA и SHA-3 завершаются с отказом как неподдерживаемые; SHA-1 понижается до CRYPTO_CONSTRAINTS_FAILURE. В профиле криптополитики Enterprise FIPS 140-3 (задокументирован вместе с модулем безопасности) ограничение применяется к тому, какие алгоритмы принимаются; сам процесс проверки — пересчёт дайджеста, проверки подписи, привязка, проверка пути — не меняется. NextPDF не обладает сертификатом FIPS 140-3, и эта страница его не заявляет.

УтверждениеСтандартПункт
Проверка базовой подписи — это переиспользуемый строительный блок для проверки меток времени и проверки со временем.ETSI EN 319 102-1§5.3.1
Ошибка целостности отображается в HASH_FAILURE; неудавшаяся проверка подписи отображается в SIG_CRYPTO_FAILURE.ETSI EN 319 102-1§5.2.7.4
Проверка формата выполняется первой, и непрохождение останавливает процесс.ETSI EN 319 102-1§5.3.4
Связанную с отзывом неопределённость можно разрешить с помощью временного доказательства.ETSI EN 319 102-1§5.3.4
Действительный путь сертификации начинается с якоря доверия, предоставленного на входе.RFC 5280§6.1
Верификатор пересчитывает дайджест содержимого; он должен быть равен подписанному атрибуту messageDigest.RFC 5652§5.6
messageImprint метки времени подписи хеширует значение поля signature из SignerInfo.RFC 3161Appendix A
Атрибут signature-time-stamp несёт ровно один AttributeValue.ETSI EN 319 122-1§5.3

Все пункты изложены в пересказе; NextPDF не воспроизводит нормативный текст. NextPDF не делает заявлений о соответствии или сертификации AdES / PAdES. Поддержка стандарта не является соответствием ему, а соответствие не является сертификацией — NextPDF не обладает сертификацией и не предоставляет её. Движок реализует цитируемые процедуры проверки как возможность; это не квалифицированная и не сертифицированная служба проверки, а отчёт TOTAL_PASSED — это криптографическое утверждение, а не юридическое определение. Значения перечислений переиспользуют шаблон идентификаторов URN ETSI для интероперабельности данных отчёта; такое переиспользование не подразумевает никакого одобрения.

  • Сопоставление меток пунктов. Исходный код пакета аннотирует точки входа как пункты EN 319 102-1 5.2, 5.3 и 5.4. Корпус соответствия помещает сам процесс проверки базовой подписи в пункт 5.3, а криптографический строительный блок — в 5.2.7.4. Эта страница цитирует извлечённые номера пунктов; авторитетен контракт поведения, а не метка.
  • Детерминированные тесты. Каждое сравнение времени проходит через внедрённый PSR-20 ClockInterface. Внедрите замороженные часы, чтобы тестировать проверки окна, границу расхождения genTime в 300 секунд и решения о свежести CRL.
  • Композиция. Все коллабораторы движка внедряются через конструктор и являются необязательными, со значениями по умолчанию fail-closed. Валидатор пути по умолчанию — CertificateChainValidator::withDefaults() поверх часов движка; параметры по умолчанию делают обработку политик и ограничений имён холостой операцией для соответствующих, неограниченных входных данных.
  • Пространства имён. Поверхность движка находится в NextPDF\Enterprise\Security\Validation, поверхность проверки пути — в NextPDF\Enterprise\Security\Pki, а пакетный оркестратор — в NextPDF\Enterprise\Signature.
  • Гигиена отчётов. Отчёты неизменяемы и сериализуются через toArray(). Диагностический контекст сбрасывается на каждой точке входа, поэтому отчёт никогда не несёт доказательств из предыдущего запуска на том же экземпляре движка.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов руководств по эксплуатации и префиксы тикетов находятся вне области действия.