Ir al contenido
getnextpdf.com

Enterprise edición

Verificación de firmas — Referencia detallada

Esta página es la referencia detallada de la superficie del lado de verificación AdES en NextPDF Enterprise. El punto de entrada es NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Implementa los flujos de validación de NextPDF modelados según ETSI para las comprobaciones de sello de tiempo básicas, con tiempo, a largo plazo y de archivo: validación básica, validación con tiempo, validación con datos a largo plazo y validación de cadena de cobertura de DocTimeStamp de archivo. Los resultados son valores ValidationReport que llevan casos de enum MainIndication y SubIndication con valores de cadena URN de ETSI. Superficies de apoyo documentadas aquí: el SPI SignatureDataExtractor y su implementación CmsSignatureDataExtractor, el escáner a nivel de bytes PdfSignatureDictionaryScanner, la superficie de validación de rutas NextPDF\Enterprise\Security\Pki y BatchSignatureValidator. Para orientación a nivel de flujo de trabajo, consulte Verificación de firmas: lado de verificación criptográfica AdES / PAdES.

Esta capacidad se incluye en NextPDF Enterprise (nextpdf/enterprise) y se activa con un sobre de licencia de nivel Enterprise. Una implementación sin ese derecho no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.

SímboloParámetrosComportamiento por defectoDevuelveLanza o falla conNotas
AdESValidationEngine::__construct11 parámetros opcionales: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy y cinco colaboradores verificadores opcionalesTodos los valores por defecto son a prueba de fallos: validador de rutas Pki sobre el reloj del motor, sin extractor, sin almacén de confianza TSANuevo motorNo lanzaSin almacén de confianza, la evaluación de la cadena TSA informa como no confiable; eso se asigna a INDETERMINATE, nunca a una aprobación
AdESValidationEngine::validateBasicstring $signedData, string $signatureValidación básica: formato, resumen, cripto, algoritmo débil, cadena, revocación condicionada a la procedenciaValidationReportNo lanza; los fallos de extracción y de ruta se asignan a informes a prueba de fallosSin un extractor, solo comprobaciones de guarda; consulte los casos límite
AdESValidationEngine::validateWithTimestring $signedData, string $signature, DateTimeImmutable $claimedTimeValidación básica primero; ventana del certificado y revocación comparadas con el tiempo declaradoValidationReportNo lanzaCompuerta estricta de sello de tiempo de firma cuando el atributo está presente; $claimedTime permanece como ancla temporal
AdESValidationEngine::validateWithLongTermDatastring $signedData, string $signature, array $dssData (certs/ocsps/crls)Se requiere aprobación básica; compuerta de sello de tiempo de firma armada con TSA-en-genTime; compuertas de POE, revocación DSS y de archivoValidationReportNo lanzaNetworkPolicy::STRICT_OFFLINE con datos incrustados insuficientes produce INDETERMINATE / TRY_LATER
AdESValidationEngine::validateArchivalTimestampChainstring $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = nullCadena de cobertura de DocTimeStamp basada en evidencia sobre los bytes exactos de ByteRangeValidationReportNo lanza ante bytes hostilesTOTAL_PASSED solo para una cadena confiable que cubre hasta EOF
MainIndicationEnum respaldado por cadena, tres casosValores URN de ETSI; consulte la lista de casos a continuación
SubIndicationEnum respaldado por cadena, quince casosValores URN de ETSI; consulte la lista de casos a continuación
ValidationReport::__constructMainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = ''Resultado de validación inmutable (final readonly)Nuevo informeNo lanzaisPassed(), isFailed(), isIndeterminate(), toArray()
DiagnosticData::__constructarray $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (todos con valor por defecto)Contenedor de evidencia inmutable; solo registro de auditoríaNuevo valorNo lanzatoArray() serializa referencias para la elaboración de informes
SignatureDataExtractor::extractstring $signedData, string $signatureSPI: analiza el CMS y extrae los componentes de validaciónExtractedSignatureDataSignatureExtractionException cuando la firma no se puede analizarInterfaz; desacopla el análisis ASN.1 del motor
CmsSignatureDataExtractor::extractstring $signedData, string $signatureExtrae y verifica criptográficamente una firma básica PAdES separadaExtractedSignatureDataSignatureExtractionException solo cuando el CMS no se puede analizar en absolutoUn fallo de cripto o de vinculación devuelve datos con cryptoValid / hashValid en falso; nunca lanza por ello
PdfSignatureDictionaryScanner::scanstring $pdfBytesEscaneo a nivel de bytes de diccionarios /ByteRange + /Contents con comprobaciones cruzadas antifalsificación de ajuste precisolist<PdfSignatureOccurrence>Total; nunca lanza; los candidatos malformados se omitenOrdenado por fin de cobertura, el más temprano primero
PathValidatorInterface::validatearray $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = []Validación de rutas según RFC 5280 §6.1.4 con procesamiento de políticasPathValidationResultPathValidationException ante una cadena estructuralmente inválida o un límite adversarial sobrepasadoLa cadena tiene la entidad final primero y el ancla al final
PathValidatorInterface::validateWithAiaChasingarray $chain, ?DateTimeImmutable $validationTime = nullResolución AIA de intermedios faltantes y luego validaciónPathValidationResultPathValidationExceptionLas descargas están limitadas por tiempo de espera y límites de bytes
CertificateChainValidatorConstructor: motor, PathValidationOptions, reloj, logger; withDefaults() estáticoLa implementación del SPI con los límites adversariales por defectoPathValidationResult de ambos métodosPathValidationExceptionTambién se lanza cuando un OpenSSLCertificate no se puede exportar a PEM
PathValidationOptions::__constructLímites (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) más indicadores de política, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchorProfundidad 32, fanout 64, 5 s por descarga, 10 MiB por descarga; todos los indicadores en falsoNuevas opcionesNo lanzaFábricas: defaults(), strict(), withTrustAnchors()
PathValidationResult::__constructbool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasonsResultado inmutable; trustAnchorTrusted por defecto es falso (a prueba de fallos)Nuevo valorNo lanzaLa pertenencia a la confianza es distinta de la validez estructural
PolicyProcessorConstructor: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree()Expansión, asignación y cierre del árbol de políticas según RFC 5280 §6.1.4void / list<non-empty-string> / PolicyTreePathValidationException ante cualquier fallo de procesamiento de políticas (a prueba de fallos)El cierre devuelve los OID de política supervivientes, excluyendo anyPolicy
PolicyTreeattach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), más consultas de lecturaEl estado valid_policy_tree con un índice de profundidadVaría según el métodoPathValidationException cuando el recuento de hojas activas supera el límite de fanoutExpone ANY_POLICY_OID (2.5.29.32.0)
NameConstraintsChecker::processCertificatestring $certDer, bool $applyNameCheckAcumula y aplica los subárboles permitidos / excluidos según RFC 5280 §6.1.4(g)voidPathValidationException ante un subárbol violado, una forma de GeneralName no admitida en una restricción o un límite sobrepasadoLos nombres no comparables se gestionan a prueba de fallos
TrustAnchorStoreInterface::containsFingerprintstring $anchorDerSha256HexPertenencia por SHA-256 en hex minúsculas sobre el certificado DER del anclaboolNo lanzaLa costura de confianza consultada por el validador de rutas
BatchSignatureValidator::validatearray $inputs (list<DocumentSignatureInput>)Validación de firmas de múltiples documentos con caché de revocación por loteBatchValidationReportInvalidArgumentException ante una lista vacía; una guarda de recursos rechaza los lotes de más de 1000 documentosReside en 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 indicación. Casos de MainIndication: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. Los valores de respaldo siguen el patrón urn:etsi:019102:mainindication:total-passed (minúsculas, con guiones). 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 uno está respaldado por urn:etsi:019102:subindication:<CASE_NAME> con el nombre de caso exacto.

  • Informes de entrada, informes de salida. Los cuatro puntos de entrada del motor devuelven un ValidationReport ante entradas hostiles en lugar de lanzar. Una SignatureExtractionException capturada se encamina a la ruta de guarda; una PathValidationException capturada se asigna a TOTAL_FAILED / CERTIFICATE_CHAIN_GENERAL_FAILURE.
  • Orden de la validación básica. Comprobación de formato primero; una estructura no analizable es TOTAL_FAILED / FORMAT_FAILURE (EN 319 102-1 §5.3.4). Luego el resumen (HASH_FAILURE) y la verificación criptográfica (SIG_CRYPTO_FAILURE), en correspondencia con los resultados de los bloques constructivos de EN 319 102-1 §5.2.7.4. El resumen lo recalcula el verificador y se compara con el atributo firmado messageDigest (RFC 5652 §5.6); nunca se confía en los resúmenes proporcionados por el productor.
  • Los algoritmos débiles degradan. Una firma que se verifica con SHA-1, o con una vinculación débil del certificado de firma, devuelve INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE, nunca TOTAL_PASSED. La ruta con tiempo reafirma esto para que una firma débil nunca se blanquee como una aprobación válida en el tiempo.
  • Compuerta de procedencia de la revocación. Los indicadores de revocación del extractor se consultan solo cuando el extractor realmente realizó una comprobación de revocación (revocationChecked verdadero). Un valor por defecto sin comprobar no es ni «verificado como no revocado» ni un desencadenante de REVOKED. La evidencia de revocación la establece la ruta DSS.
  • Propagación de no aprobación. Las rutas con tiempo y a largo plazo nunca mejoran un resultado básico de no aprobación. Existe una excepción: un INDETERMINATE / REVOKED básico se resuelve frente a $claimedTime; una revocación en el tiempo declarado o antes de él es TOTAL_FAILED / REVOKED. Esto refleja el patrón de EN 319 102-1 §5.3.4 de resolver un indeterminado relacionado con la revocación mediante evidencia temporal. Cuando la comparación no se puede realizar, el informe básico sin resolver se propaga tal cual.
  • Vinculación estricta del sello de tiempo de firma (a prueba de fallos; ruptura de compatibilidad). Cuando el CMS lleva un atributo sin firmar id-aa-timeStampToken, su presencia activa la aplicación en las rutas tanto con tiempo como a largo plazo; no existe un modo de solo advertencia. La cardinalidad debe ser exactamente un atributo con exactamente un valor (EN 319 122-1 §5.3); cualquier otra forma es TOTAL_FAILED / FORMAT_FAILURE. El token debe verificarse criptográficamente de extremo a extremo; un token no verificable, un conflicto diferencial del analizador o un desajuste de impronta es INDETERMINATE / TIMESTAMP_ORDER_FAILURE. Un algoritmo de impronta no admitido o SHA-1 es INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE. La regla de vinculación es RFC 3161 Appendix A: el messageImprint del token debe ser igual al hash de los octetos del valor signature de SignerInfo, comparado en tiempo constante.
  • Compuertas de la ruta a largo plazo. En la ruta anotada con la cláusula 5.4, el sello de tiempo de firma vinculado recibe además una evaluación del certificado TSA en el genTime del token; un ancla no confiable es INDETERMINATE / CERTIFICATE_CHAIN_GENERAL_FAILURE, nunca una aprobación. NetworkPolicy::STRICT_OFFLINE con material DSS incrustado insuficiente devuelve INDETERMINATE / TRY_LATER. Los hallazgos de prueba de existencia, revocación DSS y cadena de archivo cortocircuitan cada uno a INDETERMINATE con una subindicación asignada.
  • Compuertas de la cadena de archivo. Ningún DocTimeStamp presente es INDETERMINATE / NO_POE. Un ByteRange estructuralmente no conforme es TOTAL_FAILED / FORMAT_FAILURE. Cada token debe verificarse, vincular su impronta a los bytes exactos cubiertos por ByteRange y superar la asignación de facetas TSA-en-genTime (EXPIRED, NOT_YET_VALID, REVOKED_CA_NO_POE, CERTIFICATE_CHAIN_GENERAL_FAILURE o TRY_LATER bajo modo estricto sin conexión). Se aplica el orden: genTime no decreciente, cobertura estrictamente progresiva y tokens posteriores que contienen el hueco /Contents del token anterior. El último token debe cubrir el byte final; los bytes finales sobrantes son TIMESTAMP_ORDER_FAILURE. Un genTime más de 300 segundos por delante del reloj del verificador es TIMESTAMP_ORDER_FAILURE.
  • Los diagnósticos nunca deciden. Las entradas de prueba de existencia de DiagnosticData::$timestamps son solo registro de auditoría. Nunca cambian una indicación, y el acumulador se restablece en cada punto de entrada.
  • Los límites de Pki preceden a la cripto. Los límites de PathValidationOptions (profundidad 32, fanout de política 64, 5 s y 10 MiB por descarga) se comprueban antes del trabajo costoso. PathValidationResult::$trustAnchorTrusted es distinto de $valid; requireTrustedAnchor hace inválido un terminal no afirmado. strict() habilita requireExplicitPolicy, transporte de revocación con fallo estricto y requireTrustedAnchor. La validez de la ruta es relativa al ancla según RFC 5280 §6.1: una ruta válida comienza en un ancla de confianza proporcionada como entrada.
  • Superficie por lotes. BatchSignatureValidator::validate() lanza InvalidArgumentException ante una lista vacía y rechaza los lotes de más de 1000 documentos mediante una guarda de recursos. PHP posee toda la validación criptográfica en esa canalización.
  • El motor por defecto no tiene extractor. new AdESValidationEngine() realiza solo comprobaciones de guarda: una firma o datos firmados vacíos es TOTAL_FAILED; cualquier par no vacío se resuelve a INDETERMINATE / NO_SIGNING_CERTIFICATE_FOUND, nunca TOTAL_PASSED. Inyecte NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor para obtener verificación criptográfica.
  • La comprobación de confianza TSA por defecto no tiene almacén. Cada cadena TSA informa entonces como no confiable, por lo que los resultados de sello de tiempo de firma de archivo y a largo plazo permanecen como INDETERMINATE. Proporcione anclas mediante validateArchivalTimestampChain(..., $anchors) o un TsaCertificateAtGenTimeCheck configurado.
  • $pdfBytes vacío. validateArchivalTimestampChain('') devuelve TOTAL_FAILED / FORMAT_FAILURE.
  • Los sellos de tiempo de firma anteriores a la corrección no pueden aprobar. Los tokens producidos por versiones de NextPDF anteriores a la corrección de vinculación estricta improntaron una entrada diferente. Fallan la vinculación de Appendix A de forma permanente; vuelva a firmar y a sellar el tiempo para restaurar un resultado positivo. Esta es una ruptura de compatibilidad deliberada y documentada.
  • DocTimeStamps duplicados o solapados. Un duplicado en la misma revisión, una cobertura igual o solapada, o un token posterior que no contiene el hueco de firma del token anterior falla la compuerta de ordenación.
  • El escáner es total y a nivel de bytes. scan() omite silenciosamente los candidatos malformados o falsificados; un /ByteRange señuelo dentro de un flujo de contenido se rechaza. No resuelve objetos indirectos ni recorre la tabla de referencias cruzadas.
  • Cobertura, no accesibilidad. validateArchivalTimestampChain() demuestra la cobertura criptográfica de rango de bytes hasta el final del archivo. El análisis de accesibilidad a nivel de objeto (por ejemplo, una raíz de documento reapuntada dentro de una revisión cubierta) se declara fuera de alcance.
  • El uso directo de Pki lanza. Llamar directamente a las implementaciones de PathValidatorInterface expone PathValidationException para cadenas estructuralmente inválidas, límites sobrepasados, formas de restricción no admitidas y exportación PEM fallida de un manejador OpenSSLCertificate. El motor captura esta clase; sus propios llamadores deben gestionarla.

El lado de verificación acepta RSA PKCS#1 v1.5 con SHA-2 y ECDSA en P-256/P-384/P-521. Los tokens RSASSA-PSS, EdDSA y SHA-3 fallan de forma cerrada como no admitidos; SHA-1 degrada a CRYPTO_CONSTRAINTS_FAILURE. Bajo el perfil de política criptográfica FIPS 140-3 de Enterprise (documentado con el módulo de seguridad), la restricción se aplica a qué algoritmos se aceptan; el flujo de validación en sí —recálculo del resumen, comprobaciones de firma, vinculación, validación de rutas— no cambia. NextPDF no posee ningún certificado FIPS 140-3 y esta página no reclama ninguno.

AfirmaciónEstándarCláusula
La validación de firma básica es un bloque constructivo reutilizable para la validación de sello de tiempo y con tiempo.ETSI EN 319 102-1§5.3.1
Un fallo de integridad se asigna a HASH_FAILURE; una comprobación de firma fallida se asigna a SIG_CRYPTO_FAILURE.ETSI EN 319 102-1§5.2.7.4
La comprobación de formato se ejecuta primero y una no aprobación detiene el proceso.ETSI EN 319 102-1§5.3.4
Un indeterminado relacionado con la revocación se puede resolver con evidencia temporal.ETSI EN 319 102-1§5.3.4
Una ruta de certificación válida comienza en un ancla de confianza proporcionada como entrada.RFC 5280§6.1
El verificador recalcula el resumen del contenido; debe ser igual al atributo firmado messageDigest.RFC 5652§5.6
El messageImprint del sello de tiempo de firma aplica el hash al valor del campo signature de SignerInfo.RFC 3161Appendix A
El atributo signature-time-stamp lleva exactamente un AttributeValue.ETSI EN 319 122-1§5.3

Todas las cláusulas están parafraseadas; NextPDF no reproduce texto normativo. NextPDF no realiza ninguna afirmación de conformidad ni de certificación AdES / PAdES. La compatibilidad con un estándar no es conformidad con él, y la conformidad no es certificación: NextPDF no posee ninguna certificación ni concede ninguna. El motor implementa los procedimientos de validación citados como capacidad; no es un servicio de validación cualificado ni certificado, y un informe TOTAL_PASSED es una declaración criptográfica, no una determinación legal. Los valores de enum reutilizan el patrón de identificador URN de ETSI para la interoperabilidad de los datos de informe; esa reutilización no afirma ningún respaldo.

  • Asignación de etiquetas de cláusula. El código fuente del paquete anota los puntos de entrada como las cláusulas 5.2, 5.3 y 5.4 de EN 319 102-1. El corpus de conformidad ubica el proceso de validación de firma básica en sí en la cláusula 5.3, con el bloque constructivo criptográfico en 5.2.7.4. Esta página cita los números de cláusula recuperados; el contrato de comportamiento, no la etiqueta, es la autoridad.
  • Pruebas deterministas. Cada comparación de tiempo fluye a través del ClockInterface PSR-20 inyectado. Inyecte un reloj congelado para probar las comprobaciones de ventana, el límite de desfase de genTime de 300 segundos y las decisiones de frescura de CRL.
  • Composición. Todos los colaboradores del motor se inyectan por constructor y son opcionales, con valores por defecto a prueba de fallos. El validador de rutas por defecto es CertificateChainValidator::withDefaults() sobre el reloj del motor; las opciones por defecto mantienen el procesamiento de políticas y de restricciones de nombre como una operación nula para entradas conformes y sin restricciones.
  • Espacios de nombres. La superficie del motor reside en NextPDF\Enterprise\Security\Validation, la superficie de validación de rutas en NextPDF\Enterprise\Security\Pki y el orquestador por lotes en NextPDF\Enterprise\Signature.
  • Higiene de los informes. Los informes son inmutables y serializables mediante toArray(). El contexto de diagnóstico se restablece en cada punto de entrada, por lo que un informe nunca lleva evidencia de una ejecución anterior en la misma instancia del motor.

Esta página documenta únicamente el comportamiento observable externamente y la superficie de API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de tickets quedan fuera de alcance.