Enterprise edición
Verificación de firmas — Referencia detallada
De un vistazo
Sección titulada «De un vistazo»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.
Disponibilidad y licencias
Sección titulada «Disponibilidad y licencias»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.
Superficie de API pública
Sección titulada «Superficie de API pública»| Símbolo | Parámetros | Comportamiento por defecto | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
AdESValidationEngine::__construct | 11 parámetros opcionales: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy y cinco colaboradores verificadores opcionales | Todos 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 TSA | Nuevo motor | No lanza | Sin 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::validateBasic | string $signedData, string $signature | Validación básica: formato, resumen, cripto, algoritmo débil, cadena, revocación condicionada a la procedencia | ValidationReport | No lanza; los fallos de extracción y de ruta se asignan a informes a prueba de fallos | Sin un extractor, solo comprobaciones de guarda; consulte los casos límite |
AdESValidationEngine::validateWithTime | string $signedData, string $signature, DateTimeImmutable $claimedTime | Validación básica primero; ventana del certificado y revocación comparadas con el tiempo declarado | ValidationReport | No lanza | Compuerta estricta de sello de tiempo de firma cuando el atributo está presente; $claimedTime permanece como ancla temporal |
AdESValidationEngine::validateWithLongTermData | string $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 archivo | ValidationReport | No lanza | NetworkPolicy::STRICT_OFFLINE con datos incrustados insuficientes produce INDETERMINATE / TRY_LATER |
AdESValidationEngine::validateArchivalTimestampChain | string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null | Cadena de cobertura de DocTimeStamp basada en evidencia sobre los bytes exactos de ByteRange | ValidationReport | No lanza ante bytes hostiles | TOTAL_PASSED solo para una cadena confiable que cubre hasta EOF |
MainIndication | — | Enum respaldado por cadena, tres casos | — | — | Valores URN de ETSI; consulte la lista de casos a continuación |
SubIndication | — | Enum respaldado por cadena, quince casos | — | — | Valores URN de ETSI; consulte la lista de casos a continuación |
ValidationReport::__construct | MainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = '' | Resultado de validación inmutable (final readonly) | Nuevo informe | No lanza | isPassed(), isFailed(), isIndeterminate(), toArray() |
DiagnosticData::__construct | array $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (todos con valor por defecto) | Contenedor de evidencia inmutable; solo registro de auditoría | Nuevo valor | No lanza | toArray() serializa referencias para la elaboración de informes |
SignatureDataExtractor::extract | string $signedData, string $signature | SPI: analiza el CMS y extrae los componentes de validación | ExtractedSignatureData | SignatureExtractionException cuando la firma no se puede analizar | Interfaz; desacopla el análisis ASN.1 del motor |
CmsSignatureDataExtractor::extract | string $signedData, string $signature | Extrae y verifica criptográficamente una firma básica PAdES separada | ExtractedSignatureData | SignatureExtractionException solo cuando el CMS no se puede analizar en absoluto | Un fallo de cripto o de vinculación devuelve datos con cryptoValid / hashValid en falso; nunca lanza por ello |
PdfSignatureDictionaryScanner::scan | string $pdfBytes | Escaneo a nivel de bytes de diccionarios /ByteRange + /Contents con comprobaciones cruzadas antifalsificación de ajuste preciso | list<PdfSignatureOccurrence> | Total; nunca lanza; los candidatos malformados se omiten | Ordenado por fin de cobertura, el más temprano primero |
PathValidatorInterface::validate | array $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = [] | Validación de rutas según RFC 5280 §6.1.4 con procesamiento de políticas | PathValidationResult | PathValidationException ante una cadena estructuralmente inválida o un límite adversarial sobrepasado | La cadena tiene la entidad final primero y el ancla al final |
PathValidatorInterface::validateWithAiaChasing | array $chain, ?DateTimeImmutable $validationTime = null | Resolución AIA de intermedios faltantes y luego validación | PathValidationResult | PathValidationException | Las descargas están limitadas por tiempo de espera y límites de bytes |
CertificateChainValidator | Constructor: motor, PathValidationOptions, reloj, logger; withDefaults() estático | La implementación del SPI con los límites adversariales por defecto | PathValidationResult de ambos métodos | PathValidationException | También se lanza cuando un OpenSSLCertificate no se puede exportar a PEM |
PathValidationOptions::__construct | Límites (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) más indicadores de política, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchor | Profundidad 32, fanout 64, 5 s por descarga, 10 MiB por descarga; todos los indicadores en falso | Nuevas opciones | No lanza | Fábricas: defaults(), strict(), withTrustAnchors() |
PathValidationResult::__construct | bool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasons | Resultado inmutable; trustAnchorTrusted por defecto es falso (a prueba de fallos) | Nuevo valor | No lanza | La pertenencia a la confianza es distinta de la validez estructural |
PolicyProcessor | Constructor: 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.4 | void / list<non-empty-string> / PolicyTree | PathValidationException ante cualquier fallo de procesamiento de políticas (a prueba de fallos) | El cierre devuelve los OID de política supervivientes, excluyendo anyPolicy |
PolicyTree | attach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), más consultas de lectura | El estado valid_policy_tree con un índice de profundidad | Varía según el método | PathValidationException cuando el recuento de hojas activas supera el límite de fanout | Expone ANY_POLICY_OID (2.5.29.32.0) |
NameConstraintsChecker::processCertificate | string $certDer, bool $applyNameCheck | Acumula y aplica los subárboles permitidos / excluidos según RFC 5280 §6.1.4(g) | void | PathValidationException ante un subárbol violado, una forma de GeneralName no admitida en una restricción o un límite sobrepasado | Los nombres no comparables se gestionan a prueba de fallos |
TrustAnchorStoreInterface::containsFingerprint | string $anchorDerSha256Hex | Pertenencia por SHA-256 en hex minúsculas sobre el certificado DER del ancla | bool | No lanza | La costura de confianza consultada por el validador de rutas |
BatchSignatureValidator::validate | array $inputs (list<DocumentSignatureInput>) | Validación de firmas de múltiples documentos con caché de revocación por lote | BatchValidationReport | InvalidArgumentException ante una lista vacía; una guarda de recursos rechaza los lotes de más de 1000 documentos | Reside en 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 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.
Contrato de comportamiento
Sección titulada «Contrato de comportamiento»- Informes de entrada, informes de salida. Los cuatro puntos de entrada del motor devuelven un
ValidationReportante entradas hostiles en lugar de lanzar. UnaSignatureExtractionExceptioncapturada se encamina a la ruta de guarda; unaPathValidationExceptioncapturada se asigna aTOTAL_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 firmadomessageDigest(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, nuncaTOTAL_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 (
revocationCheckedverdadero). Un valor por defecto sin comprobar no es ni «verificado como no revocado» ni un desencadenante deREVOKED. 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/REVOKEDbásico se resuelve frente a$claimedTime; una revocación en el tiempo declarado o antes de él esTOTAL_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 esTOTAL_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 esINDETERMINATE/TIMESTAMP_ORDER_FAILURE. Un algoritmo de impronta no admitido o SHA-1 esINDETERMINATE/CRYPTO_CONSTRAINTS_FAILURE. La regla de vinculación es RFC 3161 Appendix A: elmessageImprintdel token debe ser igual al hash de los octetos del valorsignaturede 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
genTimedel token; un ancla no confiable esINDETERMINATE/CERTIFICATE_CHAIN_GENERAL_FAILURE, nunca una aprobación.NetworkPolicy::STRICT_OFFLINEcon material DSS incrustado insuficiente devuelveINDETERMINATE/TRY_LATER. Los hallazgos de prueba de existencia, revocación DSS y cadena de archivo cortocircuitan cada uno aINDETERMINATEcon una subindicación asignada. - Compuertas de la cadena de archivo. Ningún DocTimeStamp presente es
INDETERMINATE/NO_POE. Un ByteRange estructuralmente no conforme esTOTAL_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_FAILUREoTRY_LATERbajo modo estricto sin conexión). Se aplica el orden:genTimeno decreciente, cobertura estrictamente progresiva y tokens posteriores que contienen el hueco/Contentsdel token anterior. El último token debe cubrir el byte final; los bytes finales sobrantes sonTIMESTAMP_ORDER_FAILURE. UngenTimemás de 300 segundos por delante del reloj del verificador esTIMESTAMP_ORDER_FAILURE. - Los diagnósticos nunca deciden. Las entradas de prueba de existencia de
DiagnosticData::$timestampsson 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::$trustAnchorTrustedes distinto de$valid;requireTrustedAnchorhace inválido un terminal no afirmado.strict()habilitarequireExplicitPolicy, transporte de revocación con fallo estricto yrequireTrustedAnchor. 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()lanzaInvalidArgumentExceptionante 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.
Casos límite y modos de fallo
Sección titulada «Casos límite y modos de fallo»- El motor por defecto no tiene extractor.
new AdESValidationEngine()realiza solo comprobaciones de guarda: una firma o datos firmados vacíos esTOTAL_FAILED; cualquier par no vacío se resuelve aINDETERMINATE/NO_SIGNING_CERTIFICATE_FOUND, nuncaTOTAL_PASSED. InyecteNextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractorpara 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 mediantevalidateArchivalTimestampChain(..., $anchors)o unTsaCertificateAtGenTimeCheckconfigurado. $pdfBytesvacío.validateArchivalTimestampChain('')devuelveTOTAL_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/ByteRangeseñ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
PathValidatorInterfaceexponePathValidationExceptionpara cadenas estructuralmente inválidas, límites sobrepasados, formas de restricción no admitidas y exportación PEM fallida de un manejadorOpenSSLCertificate. El motor captura esta clase; sus propios llamadores deben gestionarla.
Comportamiento en modo FIPS
Sección titulada «Comportamiento en modo FIPS»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.
Conformidad
Sección titulada «Conformidad»| Afirmación | Estándar | Clá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 3161 | Appendix 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.
Notas de desarrollo
Sección titulada «Notas de desarrollo»- 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
ClockInterfacePSR-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 enNextPDF\Enterprise\Security\Pkiy el orquestador por lotes enNextPDF\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.
Véase también
Sección titulada «Véase también»- Verificación de firmas: lado de verificación criptográfica AdES / PAdES — la página de capacidad: flujo de trabajo, tabla de algoritmos, notas de actualización.
- Firma — Referencia detallada — el lado productor PAdES B-LT / B-LTA.
- Validación — Referencia detallada — comprobaciones estructurales de políticas sin criptografía.
- Seguridad — Referencia detallada — la superficie de seguridad combinada de Enterprise, incluido el perfil FIPS.
- Asignación de líneas base PAdES — B-B, B-T, B-LT, B-LTA en todas las ediciones.
Límite de publicación
Sección titulada «Límite de publicación»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.