Pular para o conteúdo
getnextpdf.com

Enterprise edição

Verificação de assinatura — Referência Profunda

Esta página é a referência aprofundada da superfície de verificação AdES no NextPDF Enterprise. O ponto de entrada é NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Ele implementa os fluxos de validação modelados em ETSI do NextPDF para verificações básica, com tempo, de longo prazo e de timestamp arquivístico: validação básica, validação com tempo, validação com dados de longo prazo e validação da cadeia de cobertura arquivística por DocTimeStamp. Os resultados são valores ValidationReport que carregam casos de enum MainIndication e SubIndication com valores de string URN ETSI. Superfícies de apoio documentadas aqui: o SPI SignatureDataExtractor e sua implementação CmsSignatureDataExtractor, o scanner em nível de byte PdfSignatureDictionaryScanner, a superfície de validação de caminho NextPDF\Enterprise\Security\Pki e o BatchSignatureValidator. Para orientação em nível de fluxo de trabalho, consulte Verificação de assinatura: lado de verificação criptográfica AdES / PAdES.

Este recurso é distribuído no NextPDF Enterprise (nextpdf/enterprise) e é ativado com um envelope de licença de nível Enterprise. Uma implantação sem esse direito não carrega as classes do recurso. Compare as edições e obtenha uma licença.

SímboloParâmetrosComportamento padrãoRetornaLança ou falha comNotas
AdESValidationEngine::__construct11 parâmetros opcionais: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy e cinco colaboradores verificadores opcionaisTodos os padrões são fail-closed: validador de caminho Pki sobre o relógio do engine, sem extrator, sem armazenamento de confiança TSANovo engineNão lançaSem armazenamento de confiança, a avaliação da cadeia TSA reporta não confiável; isso mapeia para INDETERMINATE, nunca uma aprovação
AdESValidationEngine::validateBasicstring $signedData, string $signatureValidação básica: formato, digest, criptografia, algoritmo fraco, cadeia, revogação restrita por proveniênciaValidationReportNão lança; falhas de extração e de caminho mapeiam para relatórios fail-closedSem um extrator, apenas verificações de guarda; veja os casos extremos
AdESValidationEngine::validateWithTimestring $signedData, string $signature, DateTimeImmutable $claimedTimeValidação básica primeiro; janela do certificado e revogação comparadas com o tempo reivindicadoValidationReportNão lançaGate estrito de signature-timestamp quando o atributo está presente; $claimedTime permanece a âncora de tempo
AdESValidationEngine::validateWithLongTermDatastring $signedData, string $signature, array $dssData (certs/ocsps/crls)Aprovação básica exigida; gate de signature-timestamp armado com TSA-at-genTime; gates de POE, revogação DSS e arquivísticosValidationReportNão lançaNetworkPolicy::STRICT_OFFLINE com dados embutidos insuficientes resulta em INDETERMINATE / TRY_LATER
AdESValidationEngine::validateArchivalTimestampChainstring $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = nullCadeia de cobertura DocTimeStamp baseada em evidências sobre os bytes exatos do ByteRangeValidationReportNão lança com bytes hostisTOTAL_PASSED apenas para uma cadeia confiável que cobre até o EOF
MainIndicationEnum baseado em string, três casosValores URN ETSI; veja a lista de casos abaixo
SubIndicationEnum baseado em string, quinze casosValores URN ETSI; veja a lista de casos abaixo
ValidationReport::__constructMainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = ''Resultado de validação imutável (final readonly)Novo relatórioNão lançaisPassed(), isFailed(), isIndeterminate(), toArray()
DiagnosticData::__constructarray $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (todos com padrão)Contêiner de evidências imutável; apenas trilha de auditoriaNovo valorNão lançatoArray() serializa referências para relatórios
SignatureDataExtractor::extractstring $signedData, string $signatureSPI: analisa o CMS e extrai os componentes de validaçãoExtractedSignatureDataSignatureExtractionException quando a assinatura não pode ser analisadaInterface; desacopla a análise ASN.1 do engine
CmsSignatureDataExtractor::extractstring $signedData, string $signatureExtrai e verifica criptograficamente uma assinatura básica PAdES destacadaExtractedSignatureDataSignatureExtractionException apenas quando o CMS não pode ser analisado de forma algumaUma falha de criptografia ou de vinculação retorna dados com cryptoValid / hashValid falso; nunca lança para isso
PdfSignatureDictionaryScanner::scanstring $pdfBytesVarredura em nível de byte por dicionários /ByteRange + /Contents com verificações cruzadas anti-spoof de ajuste precisolist<PdfSignatureOccurrence>Total; nunca lança; candidatos malformados são ignoradosOrdenado pelo fim da cobertura, do mais antigo primeiro
PathValidatorInterface::validatearray $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = []Validação de caminho RFC 5280 §6.1.4 com processamento de políticasPathValidationResultPathValidationException em uma cadeia estruturalmente inválida ou um limite adversarial violadoA cadeia é entidade-final primeiro, âncora por último
PathValidatorInterface::validateWithAiaChasingarray $chain, ?DateTimeImmutable $validationTime = nullResolução AIA de intermediários ausentes, depois validaçãoPathValidationResultPathValidationExceptionAs buscas são limitadas por timeout e por limites de bytes
CertificateChainValidatorConstrutor: engine, PathValidationOptions, relógio, logger; estático withDefaults()A implementação do SPI com os limites adversariais padrãoPathValidationResult de ambos os métodosPathValidationExceptionTambém lançada quando um OpenSSLCertificate não pode ser exportado para PEM
PathValidationOptions::__constructLimites (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) mais flags de política, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchorProfundidade 32, fanout 64, 5 s por busca, 10 MiB por busca; todas as flags falsasNovas opçõesNão lançaFábricas: defaults(), strict(), withTrustAnchors()
PathValidationResult::__constructbool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasonsResultado imutável; trustAnchorTrusted é falso por padrão (fail-closed)Novo valorNão lançaA pertinência de confiança é distinta da validade estrutural
PolicyProcessorConstrutor: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree()Expansão, mapeamento e finalização da árvore de políticas RFC 5280 §6.1.4void / list<non-empty-string> / PolicyTreePathValidationException em qualquer falha de processamento de políticas (fail-closed)A finalização retorna os OIDs de política sobreviventes, excluindo anyPolicy
PolicyTreeattach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), mais consultas de leituraO estado valid_policy_tree com um índice de profundidadeVaria por métodoPathValidationException quando a contagem de folhas ativas excede o limite de fanoutExpõe ANY_POLICY_OID (2.5.29.32.0)
NameConstraintsChecker::processCertificatestring $certDer, bool $applyNameCheckAcumula e aplica subárvores permitidas / excluídas conforme RFC 5280 §6.1.4(g)voidPathValidationException em uma subárvore violada, uma forma de GeneralName não suportada em uma restrição ou um limite violadoNomes não comparáveis são tratados fail-closed
TrustAnchorStoreInterface::containsFingerprintstring $anchorDerSha256HexPertinência por SHA-256 hex minúsculo sobre o certificado DER da âncoraboolNão lançaO ponto de confiança consultado pelo validador de caminho
BatchSignatureValidator::validatearray $inputs (list<DocumentSignatureInput>)Validação de assinatura multidocumento com cache de revogação por loteBatchValidationReportInvalidArgumentException em uma lista vazia; um guard de recurso rejeita lotes acima de 1000 documentosReside em 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

Enums de indicação. Casos de MainIndication: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. Os valores de apoio seguem o padrão urn:etsi:019102:mainindication:total-passed (minúsculo, com hifens). Casos de 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. Cada um é apoiado por urn:etsi:019102:subindication:<CASE_NAME> com o nome exato do caso.

  • Relatórios entram, relatórios saem. Os quatro pontos de entrada do engine retornam um ValidationReport para entrada hostil em vez de lançar. Uma SignatureExtractionException capturada é encaminhada para o caminho de guarda; uma PathValidationException capturada mapeia para TOTAL_FAILED / CERTIFICATE_CHAIN_GENERAL_FAILURE.
  • Ordem da validação básica. Verificação de formato primeiro; uma estrutura não analisável é TOTAL_FAILED / FORMAT_FAILURE (EN 319 102-1 §5.3.4). Depois digest (HASH_FAILURE) e verificação criptográfica (SIG_CRYPTO_FAILURE), correspondendo aos resultados de bloco de construção da EN 319 102-1 §5.2.7.4. O digest é recomputado pelo verificador e comparado com o atributo assinado messageDigest (RFC 5652 §5.6); digests fornecidos pelo produtor nunca são confiáveis.
  • Algoritmos fracos são degradados. Uma assinatura que verifica sob SHA-1, ou com uma vinculação fraca ao certificado de assinatura, retorna INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE, nunca TOTAL_PASSED. O caminho de tempo reafirma isso para que uma assinatura fraca nunca seja lavada em uma aprovação válida no tempo.
  • Gate de proveniência de revogação. As flags de revogação do extrator só são consultadas quando o extrator efetivamente realizou uma verificação de revogação (revocationChecked verdadeiro). Um padrão não verificado não é nem “verificado como não revogado” nem um gatilho de REVOKED. A evidência de revogação é estabelecida pelo caminho DSS.
  • Propagação de não aprovação. Os caminhos de tempo e de longo prazo nunca elevam um resultado básico de não aprovação. Existe uma exceção: um INDETERMINATE / REVOKED básico é resolvido contra $claimedTime; a revogação no tempo reivindicado ou antes dele é TOTAL_FAILED / REVOKED. Isso espelha o padrão da EN 319 102-1 §5.3.4 de resolver um indeterminado relacionado a revogação com evidência de tempo. Quando a comparação não pode ser realizada, o relatório básico não resolvido é propagado verbatim.
  • Vinculação estrita de signature-timestamp (fail-closed; quebra de BC). Quando o CMS carrega um atributo não assinado id-aa-timeStampToken, sua presença dispara a imposição tanto no caminho de tempo quanto no de longo prazo; não há modo somente-aviso. A cardinalidade deve ser exatamente um atributo com exatamente um valor (EN 319 122-1 §5.3); qualquer outra forma é TOTAL_FAILED / FORMAT_FAILURE. O token deve verificar criptograficamente de ponta a ponta; um token não verificável, um conflito de parser-differential ou uma incompatibilidade de imprint é INDETERMINATE / TIMESTAMP_ORDER_FAILURE. Um algoritmo de imprint não suportado ou SHA-1 é INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE. A regra de vinculação é RFC 3161 Appendix A: o messageImprint do token deve igualar o hash dos octetos do valor signature do SignerInfo, comparados em tempo constante.
  • Gates do caminho de longo prazo. No caminho anotado com a cláusula 5.4, o signature timestamp vinculado recebe adicionalmente a avaliação do certificado TSA no genTime do token; uma âncora não confiável é INDETERMINATE / CERTIFICATE_CHAIN_GENERAL_FAILURE, nunca uma aprovação. NetworkPolicy::STRICT_OFFLINE com material DSS embutido insuficiente retorna INDETERMINATE / TRY_LATER. Provas de existência, revogação DSS e achados da cadeia arquivística fazem cada um curto-circuito para INDETERMINATE com uma sub-indicação mapeada.
  • Gates da cadeia arquivística. Nenhum DocTimeStamp presente é INDETERMINATE / NO_POE. Um ByteRange estruturalmente não conforme é TOTAL_FAILED / FORMAT_FAILURE. Cada token deve verificar, vincular seu imprint aos bytes exatos cobertos pelo ByteRange e passar no mapeamento de faceta TSA-at-genTime (EXPIRED, NOT_YET_VALID, REVOKED_CA_NO_POE, CERTIFICATE_CHAIN_GENERAL_FAILURE ou TRY_LATER sob strict-offline). A ordenação é imposta: genTime não decrescente, cobertura estritamente progressiva e tokens posteriores contendo o buraco /Contents do token anterior. O token mais recente deve cobrir o byte final; bytes finais são TIMESTAMP_ORDER_FAILURE. Um genTime mais de 300 segundos à frente do relógio do verificador é TIMESTAMP_ORDER_FAILURE.
  • Diagnósticos nunca decidem. As entradas de prova de existência de DiagnosticData::$timestamps são apenas trilha de auditoria. Elas nunca alteram uma indicação, e o acumulador é reiniciado a cada ponto de entrada.
  • Limites do Pki precedem a criptografia. Os limites de PathValidationOptions (profundidade 32, fanout de política 64, 5 s e 10 MiB por busca) são verificados antes de trabalho custoso. PathValidationResult::$trustAnchorTrusted é distinto de $valid; requireTrustedAnchor torna um término não confirmado inválido. strict() habilita requireExplicitPolicy, transporte de revogação com falha rígida e requireTrustedAnchor. A validade do caminho é relativa à âncora conforme RFC 5280 §6.1: um caminho válido começa em uma âncora de confiança fornecida como entrada.
  • Superfície de lote. BatchSignatureValidator::validate() lança InvalidArgumentException para uma lista vazia e rejeita lotes acima de 1000 documentos por meio de um guard de recurso. O PHP é dono de toda a validação criptográfica nesse pipeline.
  • O engine padrão não tem extrator. new AdESValidationEngine() realiza apenas verificações de guarda: assinatura ou dados assinados vazios é TOTAL_FAILED; qualquer par não vazio resolve para INDETERMINATE / NO_SIGNING_CERTIFICATE_FOUND, nunca TOTAL_PASSED. Injete NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor para obter verificação criptográfica.
  • A verificação de confiança TSA padrão não tem armazenamento. Toda cadeia TSA então reporta não confiável, de modo que os resultados de signature-timestamp arquivístico e de longo prazo permanecem INDETERMINATE. Forneça âncoras via validateArchivalTimestampChain(..., $anchors) ou um TsaCertificateAtGenTimeCheck configurado.
  • $pdfBytes vazio. validateArchivalTimestampChain('') retorna TOTAL_FAILED / FORMAT_FAILURE.
  • Signature timestamps anteriores à correção não podem passar. Tokens produzidos por versões do NextPDF anteriores à correção de vinculação estrita imprimiram uma entrada diferente. Eles falham permanentemente na vinculação do Appendix A; assine e carimbe o tempo novamente para restaurar um resultado positivo. Esta é uma quebra de BC deliberada e documentada.
  • DocTimeStamps duplicados ou sobrepostos. Uma duplicata na mesma revisão, cobertura igual ou sobreposta, ou um token posterior que não contém o buraco de assinatura do token anterior falha no gate de ordenação.
  • O scanner é total e em nível de byte. scan() ignora candidatos malformados ou falsificados silenciosamente; um /ByteRange isca dentro de um content stream é rejeitado. Ele não resolve objetos indiretos nem percorre a tabela de referência cruzada.
  • Cobertura, não alcançabilidade. validateArchivalTimestampChain() prova a cobertura criptográfica do intervalo de bytes até o fim do arquivo. A análise de alcançabilidade em nível de objeto (por exemplo, uma raiz de documento reapontada dentro de uma revisão coberta) é declarada fora do escopo.
  • O uso direto do Pki lança. Chamar implementações de PathValidatorInterface diretamente expõe PathValidationException para cadeias estruturalmente inválidas, limites violados, formas de restrição não suportadas e falha de exportação PEM de um handle OpenSSLCertificate. O engine captura essa classe; seus próprios chamadores devem tratá-la.

O lado de verificação aceita RSA PKCS#1 v1.5 com SHA-2 e ECDSA em P-256/P-384/P-521. Tokens RSASSA-PSS, EdDSA e SHA-3 falham fechados como não suportados; SHA-1 degrada para CRYPTO_CONSTRAINTS_FAILURE. Sob o perfil de política criptográfica FIPS 140-3 do Enterprise (documentado com o módulo de segurança), a restrição se aplica a quais algoritmos são aceitos; o próprio fluxo de validação — recomputação de digest, verificações de assinatura, vinculação, validação de caminho — permanece inalterado. O NextPDF não possui certificado FIPS 140-3 e esta página não reivindica nenhum.

ReivindicaçãoPadrãoCláusula
A validação de Basic Signature é um bloco de construção reutilizável para a validação com time-stamp e com tempo.ETSI EN 319 102-1§5.3.1
Falha de integridade mapeia para HASH_FAILURE; uma verificação de assinatura falha mapeia para SIG_CRYPTO_FAILURE.ETSI EN 319 102-1§5.2.7.4
A verificação de formato roda primeiro e uma não aprovação interrompe o processo.ETSI EN 319 102-1§5.3.4
Um indeterminado relacionado a revogação pode ser resolvido com evidência de tempo.ETSI EN 319 102-1§5.3.4
Um caminho de certificação válido começa em uma âncora de confiança fornecida como entrada.RFC 5280§6.1
O verificador recomputa o digest do conteúdo; ele deve igualar o atributo assinado messageDigest.RFC 5652§5.6
O messageImprint do signature timestamp faz o hash do valor do campo signature do SignerInfo.RFC 3161Appendix A
O atributo signature-time-stamp carrega exatamente um AttributeValue.ETSI EN 319 122-1§5.3

Todas as cláusulas são parafraseadas; o NextPDF não reproduz texto normativo. O NextPDF não faz nenhuma reivindicação de conformidade ou certificação AdES / PAdES. O suporte a um padrão não é conformidade com ele, e conformidade não é certificação — o NextPDF não possui certificação e não concede nenhuma. O engine implementa os procedimentos de validação citados como capacidade; não é um serviço de validação qualificado ou certificado, e um relatório TOTAL_PASSED é uma declaração criptográfica, não uma determinação legal. Os valores de enum reutilizam o padrão de identificador URN ETSI para interoperabilidade de dados de relatório; essa reutilização não afirma nenhum endosso.

  • Mapeamento de rótulos de cláusula. O código-fonte do pacote anota os pontos de entrada como cláusulas 5.2, 5.3 e 5.4 da EN 319 102-1. O corpus de conformidade coloca o próprio processo de validação de Basic Signature na cláusula 5.3, com o bloco de construção criptográfico em 5.2.7.4. Esta página cita os números de cláusula recuperados; o contrato de comportamento, não o rótulo, é autoritativo.
  • Testes determinísticos. Toda comparação de tempo flui através do ClockInterface PSR-20 injetado. Injete um relógio congelado para testar verificações de janela, o limite de skew de 300 segundos no genTime e decisões de frescor de CRL.
  • Composição. Todos os colaboradores do engine são injetados por construtor e opcionais, com padrões fail-closed. O validador de caminho padrão é CertificateChainValidator::withDefaults() sobre o relógio do engine; as opções padrão mantêm o processamento de política e de restrição de nome como um no-op para entradas conformes e sem restrições.
  • Namespaces. A superfície do engine reside em NextPDF\Enterprise\Security\Validation, a superfície de validação de caminho em NextPDF\Enterprise\Security\Pki e o orquestrador de lote em NextPDF\Enterprise\Signature.
  • Higiene de relatório. Os relatórios são imutáveis e serializáveis via toArray(). O contexto de diagnóstico é reiniciado a cada ponto de entrada, de modo que um relatório nunca carrega evidências de uma execução anterior na mesma instância do engine.

Esta página documenta apenas o comportamento observável externamente e a superfície da API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de tíquete estão fora do escopo.