Enterprise edição
Verificação de assinatura — Referência Profunda
Visão geral
Seção intitulada “Visão geral”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.
Disponibilidade e licenciamento
Seção intitulada “Disponibilidade e licenciamento”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.
Superfície da API pública
Seção intitulada “Superfície da API pública”| Símbolo | Parâmetros | Comportamento padrão | Retorna | Lança ou falha com | Notas |
|---|---|---|---|---|---|
AdESValidationEngine::__construct | 11 parâmetros opcionais: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy e cinco colaboradores verificadores opcionais | Todos os padrões são fail-closed: validador de caminho Pki sobre o relógio do engine, sem extrator, sem armazenamento de confiança TSA | Novo engine | Não lança | Sem armazenamento de confiança, a avaliação da cadeia TSA reporta não confiável; isso mapeia para INDETERMINATE, nunca uma aprovação |
AdESValidationEngine::validateBasic | string $signedData, string $signature | Validação básica: formato, digest, criptografia, algoritmo fraco, cadeia, revogação restrita por proveniência | ValidationReport | Não lança; falhas de extração e de caminho mapeiam para relatórios fail-closed | Sem um extrator, apenas verificações de guarda; veja os casos extremos |
AdESValidationEngine::validateWithTime | string $signedData, string $signature, DateTimeImmutable $claimedTime | Validação básica primeiro; janela do certificado e revogação comparadas com o tempo reivindicado | ValidationReport | Não lança | Gate estrito de signature-timestamp quando o atributo está presente; $claimedTime permanece a âncora de tempo |
AdESValidationEngine::validateWithLongTermData | string $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ísticos | ValidationReport | Não lança | NetworkPolicy::STRICT_OFFLINE com dados embutidos insuficientes resulta em INDETERMINATE / TRY_LATER |
AdESValidationEngine::validateArchivalTimestampChain | string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null | Cadeia de cobertura DocTimeStamp baseada em evidências sobre os bytes exatos do ByteRange | ValidationReport | Não lança com bytes hostis | TOTAL_PASSED apenas para uma cadeia confiável que cobre até o EOF |
MainIndication | — | Enum baseado em string, três casos | — | — | Valores URN ETSI; veja a lista de casos abaixo |
SubIndication | — | Enum baseado em string, quinze casos | — | — | Valores URN ETSI; veja a lista de casos abaixo |
ValidationReport::__construct | MainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = '' | Resultado de validação imutável (final readonly) | Novo relatório | Não lança | isPassed(), isFailed(), isIndeterminate(), toArray() |
DiagnosticData::__construct | array $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 auditoria | Novo valor | Não lança | toArray() serializa referências para relatórios |
SignatureDataExtractor::extract | string $signedData, string $signature | SPI: analisa o CMS e extrai os componentes de validação | ExtractedSignatureData | SignatureExtractionException quando a assinatura não pode ser analisada | Interface; desacopla a análise ASN.1 do engine |
CmsSignatureDataExtractor::extract | string $signedData, string $signature | Extrai e verifica criptograficamente uma assinatura básica PAdES destacada | ExtractedSignatureData | SignatureExtractionException apenas quando o CMS não pode ser analisado de forma alguma | Uma falha de criptografia ou de vinculação retorna dados com cryptoValid / hashValid falso; nunca lança para isso |
PdfSignatureDictionaryScanner::scan | string $pdfBytes | Varredura em nível de byte por dicionários /ByteRange + /Contents com verificações cruzadas anti-spoof de ajuste preciso | list<PdfSignatureOccurrence> | Total; nunca lança; candidatos malformados são ignorados | Ordenado pelo fim da cobertura, do mais antigo primeiro |
PathValidatorInterface::validate | array $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = [] | Validação de caminho RFC 5280 §6.1.4 com processamento de políticas | PathValidationResult | PathValidationException em uma cadeia estruturalmente inválida ou um limite adversarial violado | A cadeia é entidade-final primeiro, âncora por último |
PathValidatorInterface::validateWithAiaChasing | array $chain, ?DateTimeImmutable $validationTime = null | Resolução AIA de intermediários ausentes, depois validação | PathValidationResult | PathValidationException | As buscas são limitadas por timeout e por limites de bytes |
CertificateChainValidator | Construtor: engine, PathValidationOptions, relógio, logger; estático withDefaults() | A implementação do SPI com os limites adversariais padrão | PathValidationResult de ambos os métodos | PathValidationException | Também lançada quando um OpenSSLCertificate não pode ser exportado para PEM |
PathValidationOptions::__construct | Limites (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) mais flags de política, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchor | Profundidade 32, fanout 64, 5 s por busca, 10 MiB por busca; todas as flags falsas | Novas opções | Não lança | Fábricas: defaults(), strict(), withTrustAnchors() |
PathValidationResult::__construct | bool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasons | Resultado imutável; trustAnchorTrusted é falso por padrão (fail-closed) | Novo valor | Não lança | A pertinência de confiança é distinta da validade estrutural |
PolicyProcessor | Construtor: 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.4 | void / list<non-empty-string> / PolicyTree | PathValidationException em qualquer falha de processamento de políticas (fail-closed) | A finalização retorna os OIDs de política sobreviventes, excluindo anyPolicy |
PolicyTree | attach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), mais consultas de leitura | O estado valid_policy_tree com um índice de profundidade | Varia por método | PathValidationException quando a contagem de folhas ativas excede o limite de fanout | Expõe ANY_POLICY_OID (2.5.29.32.0) |
NameConstraintsChecker::processCertificate | string $certDer, bool $applyNameCheck | Acumula e aplica subárvores permitidas / excluídas conforme RFC 5280 §6.1.4(g) | void | PathValidationException em uma subárvore violada, uma forma de GeneralName não suportada em uma restrição ou um limite violado | Nomes não comparáveis são tratados fail-closed |
TrustAnchorStoreInterface::containsFingerprint | string $anchorDerSha256Hex | Pertinência por SHA-256 hex minúsculo sobre o certificado DER da âncora | bool | Não lança | O ponto de confiança consultado pelo validador de caminho |
BatchSignatureValidator::validate | array $inputs (list<DocumentSignatureInput>) | Validação de assinatura multidocumento com cache de revogação por lote | BatchValidationReport | InvalidArgumentException em uma lista vazia; um guard de recurso rejeita lotes acima de 1000 documentos | Reside em NextPDF\Enterprise\Signature |
final class AdESValidationEnginepublic function validateBasic(string $signedData, string $signature): ValidationReportpublic function validateWithTime( string $signedData, string $signature, DateTimeImmutable $claimedTime,): ValidationReportpublic function validateWithLongTermData( string $signedData, string $signature, array $dssData,): ValidationReportpublic function validateArchivalTimestampChain( string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null,): ValidationReportpublic 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,): selfpublic function containsFingerprint(string $anchorDerSha256Hex): bool;public function extract(string $signedData, string $signature): ExtractedSignatureData;public function scan(string $pdfBytes): arraypublic function validate(array $inputs): BatchValidationReportEnums 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.
Contrato de comportamento
Seção intitulada “Contrato de comportamento”- Relatórios entram, relatórios saem. Os quatro pontos de entrada do engine retornam um
ValidationReportpara entrada hostil em vez de lançar. UmaSignatureExtractionExceptioncapturada é encaminhada para o caminho de guarda; umaPathValidationExceptioncapturada mapeia paraTOTAL_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 assinadomessageDigest(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, nuncaTOTAL_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 (
revocationCheckedverdadeiro). Um padrão não verificado não é nem “verificado como não revogado” nem um gatilho deREVOKED. 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/REVOKEDbá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: omessageImprintdo token deve igualar o hash dos octetos do valorsignaturedo 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
genTimedo token; uma âncora não confiável éINDETERMINATE/CERTIFICATE_CHAIN_GENERAL_FAILURE, nunca uma aprovação.NetworkPolicy::STRICT_OFFLINEcom material DSS embutido insuficiente retornaINDETERMINATE/TRY_LATER. Provas de existência, revogação DSS e achados da cadeia arquivística fazem cada um curto-circuito paraINDETERMINATEcom 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_FAILUREouTRY_LATERsob strict-offline). A ordenação é imposta:genTimenão decrescente, cobertura estritamente progressiva e tokens posteriores contendo o buraco/Contentsdo token anterior. O token mais recente deve cobrir o byte final; bytes finais sãoTIMESTAMP_ORDER_FAILURE. UmgenTimemais 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::$timestampssã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;requireTrustedAnchortorna um término não confirmado inválido.strict()habilitarequireExplicitPolicy, transporte de revogação com falha rígida erequireTrustedAnchor. 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çaInvalidArgumentExceptionpara 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.
Casos extremos e modos de falha
Seção intitulada “Casos extremos e modos de falha”- 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 paraINDETERMINATE/NO_SIGNING_CERTIFICATE_FOUND, nuncaTOTAL_PASSED. InjeteNextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractorpara 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 viavalidateArchivalTimestampChain(..., $anchors)ou umTsaCertificateAtGenTimeCheckconfigurado. $pdfBytesvazio.validateArchivalTimestampChain('')retornaTOTAL_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/ByteRangeisca 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
PathValidatorInterfacediretamente expõePathValidationExceptionpara cadeias estruturalmente inválidas, limites violados, formas de restrição não suportadas e falha de exportação PEM de um handleOpenSSLCertificate. O engine captura essa classe; seus próprios chamadores devem tratá-la.
Comportamento em modo FIPS
Seção intitulada “Comportamento em modo FIPS”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.
Conformidade
Seção intitulada “Conformidade”| Reivindicação | Padrão | Clá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 3161 | Appendix 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.
Notas de desenvolvimento
Seção intitulada “Notas de desenvolvimento”- 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
ClockInterfacePSR-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 emNextPDF\Enterprise\Security\Pkie o orquestrador de lote emNextPDF\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.
Veja também
Seção intitulada “Veja também”- Verificação de assinatura: lado de verificação criptográfica AdES / PAdES — a página do recurso: fluxo de trabalho, tabela de algoritmos, notas de atualização.
- Assinatura — Referência aprofundada — o lado produtor PAdES B-LT / B-LTA.
- Validação — Referência aprofundada — verificações de política estrutural sem criptografia.
- Segurança — Referência aprofundada — a superfície de segurança combinada do Enterprise, incluindo o perfil FIPS.
- Mapeamento de cláusulas PAdES — B-B, B-T, B-LT, B-LTA entre as edições.
Limite de publicação
Seção intitulada “Limite de publicação”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.