Resolución de problemas: fallos de firma y marca de tiempo
Alcance
Sección titulada «Alcance»Estas entradas cubren los fallos de firma que el motor lanza mediante NextPDF\Exception\SignatureException y NextPDF\Security\Signature\Exception\SignatureLevelUnreachableException. Cada entrada nombra el método de fábrica o la clase exacta para poder confirmar la causa a partir del mensaje y de getContext(), en lugar de inferirla.
Nota sobre la redacción: el motor no certifica que una firma sea válida ni que un documento esté protegido. Informa del fallo detectado. Conviene tratar cada resolución como un paso para eliminar una causa reportada.
Entrada: no se puede generar el nivel PAdES «B-LT» o «B-LTA»
Sección titulada «Entrada: no se puede generar el nivel PAdES «B-LT» o «B-LTA»»- Síntoma.
SignatureExceptioncon el final de mensajenextpdf/enterprise package is required for B-LT/B-LTA signatures. - Causa probable. Falta el proveedor de la capacidad de validación a largo plazo. B-LT y B-LTA incrustan material de revocación y una marca de tiempo de archivo; ese proveedor se distribuye en
nextpdf/enterprise. - Evidencia / diagnóstico. La fábrica
SignatureException::ltvCapabilityMissing()produce este mensaje exacto.getContext()devuelvesignature_levelfijado en el nivel que se intentó. - Resolución.
- Instalar el proveedor: ejecutar
composer require nextpdf/enterprise. - Volver a ejecutar la llamada de firma.
- Si no se puede instalar el proveedor, solicitar en su lugar
B-BoB-T, que el paquete del núcleo produce.
- Instalar el proveedor: ejecutar
- Relacionado. Referencia de excepciones.
Entrada: el nivel de firma es inalcanzable y la llamada se rechaza
Sección titulada «Entrada: el nivel de firma es inalcanzable y la llamada se rechaza»- Síntoma.
SignatureLevelUnreachableExceptioncon un mensaje de la formaPAdES level "<x>" is unreachable (highest achievable: "<y>"). - Causa probable. El nivel de conformidad solicitado requiere infraestructura que no está disponible en el momento de firmar: normalmente, una autoridad de marca de tiempo para B-T y superiores. El motor falla de forma cerrada: no aplica una degradación silenciosa para después anunciar el nivel superior.
- Evidencia / diagnóstico.
getContext()devuelverequestedLevel,highestAchievableLevelyreason. El camporeasonindica la carencia de infraestructura. Este es el comportamiento de fallo cerrado predeterminado, introducido para evitar que un documento afirme un nivel que no cumple. - Resolución.
- Leer el campo
reasonpara identificar la infraestructura que falta. - Aportar el componente que falta (por ejemplo, configurar una autoridad de marca de tiempo) y volver a ejecutar la llamada.
- Para aceptar a propósito un nivel inferior, pasar
allowDegradation: trueaPadesOrchestrator. La llamada produce entonceshighestAchievableLevele informa del nivel que produjo.
- Leer el campo
- Relacionado. Cifrado y permisos.
Entrada: el cliente de la autoridad de marca de tiempo es obligatorio, pero está ausente
Sección titulada «Entrada: el cliente de la autoridad de marca de tiempo es obligatorio, pero está ausente»- Síntoma.
SignatureExceptioncon el finalTSA client is required for level <x> but none was provided. - Causa probable. Una solicitud B-T, B-LT o B-LTA necesita un cliente de autoridad de marca de tiempo, y no se conectó ninguno al orquestador.
- Evidencia / diagnóstico. La fábrica
SignatureException::tsaRequired()produce este mensaje;getContext()incluye elsignature_levelque se intentó. - Resolución.
- Configurar un cliente de autoridad de marca de tiempo y pasarlo al orquestador.
- Volver a ejecutar la llamada.
- Para producir un nivel que no necesite marca de tiempo, solicitar
B-B.
- Relacionado. Referencia de excepciones.
Entrada: la URL del extremo de la autoridad de marca de tiempo está vacía
Sección titulada «Entrada: la URL del extremo de la autoridad de marca de tiempo está vacía»- Síntoma.
SignatureExceptioncon el finalTSA endpoint URL is empty. - Causa probable. Se construyó un cliente de autoridad de marca de tiempo con una URL de extremo vacía.
- Evidencia / diagnóstico. La fábrica
SignatureException::tsaUrlEmpty()produce este mensaje. Es un defecto de configuración, no un fallo de red. - Resolución.
- Definir una URL de extremo no vacía en el cliente de la autoridad de marca de tiempo, por ejemplo
https://timestamp.example.com/tsa. - Si la marca de tiempo no es obligatoria en el nivel solicitado, eliminar en su lugar la conexión del cliente de la autoridad de marca de tiempo.
- Volver a ejecutar la llamada.
- Definir una URL de extremo no vacía en el cliente de la autoridad de marca de tiempo, por ejemplo
- Relacionado. Referencia de excepciones.
Entrada: falta el marcador de posición de firma en el búfer
Sección titulada «Entrada: falta el marcador de posición de firma en el búfer»- Síntoma.
SignatureExceptioncon el finalno /Contents <…> field found in PDF buffer (signature placeholder missing). - Causa probable. La etapa de firma se ejecutó contra un búfer que no contiene un contenedor de firma reservado, por lo que no hay dónde escribir la firma.
- Evidencia / diagnóstico. La fábrica
SignatureException::signatureContentsNotFound()produce este mensaje. - Resolución.
- Asegurarse de que el campo de firma y su marcador de posición se escriban antes de que se ejecute la etapa de firma.
- Volver a ejecutar la canalización para que el marcador de posición exista cuando empiece la firma.
- Relacionado. Referencia de excepciones.
Entrada: el estado de revocación es desconocido (el respondedor OCSP rechazó la solicitud)
Sección titulada «Entrada: el estado de revocación es desconocido (el respondedor OCSP rechazó la solicitud)»- Síntoma.
SignatureExceptioncon el finalOCSP responder returned non-successful OCSPResponseStatus "<status>". - Causa probable. El respondedor OCSP no devolvió un estado
successful, por lo que no produjo ninguna aserción de revocación. El motor sigue la RFC 6960 §4.2.1, citada en el código fuente: solo se permite un cuerpo de respuesta con contenido para el estadosuccessful (0). El motor se niega a tratar una respuesta rechazada como un resultado positivo de confianza. - Evidencia / diagnóstico. La fábrica
SignatureException::nonSuccessfulOcspResponseStatus()produce este mensaje y nombra el estado reportado, por ejemplotryLaterointernalError. Un byte de estado reservado o desconocido produce, en cambio,SignatureException::reservedOcspResponseStatus(). - Resolución.
- Identificar el estado en el mensaje. Para un estado transitorio como
tryLater, volver a intentar la obtención de la revocación más tarde. - Para
unauthorizedomalformedRequest, verificar la URL de la solicitud OCSP y el certificado que el respondedor espera. - No suprimir el fallo para obtener un artefacto B-LT o B-LTA; la aserción de revocación forma parte de ese nivel.
- Identificar el estado en el mensaje. Para un estado transitorio como
- Relacionado. Referencia de excepciones.
Entrada: una entrada de la cadena de certificados no se puede decodificar
Sección titulada «Entrada: una entrada de la cadena de certificados no se puede decodificar»- Síntoma.
SignatureExceptioncon el finalfailed to base64-decode PEM body — input is not valid PEM. - Causa probable. Una entrada de la cadena de certificados no es PEM válido: normalmente por truncamiento, un carácter extraño o un blob DER binario suministrado donde se esperaba PEM.
- Evidencia / diagnóstico. La fábrica
SignatureException::pemDecodingFailed()produce este mensaje durante el ensamblaje de la cadena. - Resolución.
- Inspeccionar cada certificado de la cadena en busca de caracteres extraños o truncamiento.
- Volver a exportar el certificado afectado en formato PEM.
- Volver a ejecutar la llamada de firma.
- Relacionado. Cifrado y permisos.
Entrada: el tipo de clave privada no coincide con el algoritmo
Sección titulada «Entrada: el tipo de clave privada no coincide con el algoritmo»- Síntoma.
SignatureExceptioncon el finalexpected private key of type "<x>" for the configured algorithm but got "<y>". - Causa probable. La clave privada cargada no coincide con el algoritmo de firma configurado; por ejemplo, una clave RSA con una selección ECDSA.
- Evidencia / diagnóstico. La fábrica
SignatureException::unexpectedKeyType()produce este mensaje y nombra tanto la clase de clave esperada como la real. - Resolución.
- Verificar que el certificado y el par de claves coincidan con el algoritmo seleccionado.
- Cambiar la selección del algoritmo para que coincida con la clave, o cargar la clave que coincida con el algoritmo.
- Volver a ejecutar la llamada de firma.
- Relacionado. Referencia de excepciones.
Entrada: el material de clave o de firma Ed25519 está malformado
Sección titulada «Entrada: el material de clave o de firma Ed25519 está malformado»- Síntoma.
SignatureExceptioncon un final que nombra un desajuste de longitud Ed25519; por ejemploEd25519 signature length <n> ≠ expected 64 bytes, oEd25519 round-trip self-verify failed. - Causa probable. La compilación criptográfica del entorno de ejecución devolvió material de clave o de firma con una longitud incorrecta, o una firma recién producida no se verificó con su propia clave pública. El motor cita la RFC 8032 §3.4 en el código fuente, que establece una firma Ed25519 separada en 64 bytes. El motor aborta en lugar de emitir material que no puede verificar por sí mismo.
- Evidencia / diagnóstico. Las fábricas relevantes son
SignatureException::ed25519SignatureMalformed(),::ed25519RoundTripVerifyFailed(),::ed25519KeyParseFailed(),::ed25519SeedInvalid(),::ed25519SecretKeyMalformed()y::ed25519PublicKeyInvalid(). Cada una nombra la longitud observada. - Resolución.
- Reinstalar la extensión de PHP libsodium; una compilación reducida o corrupta es la causa documentada de material con longitud incorrecta.
- Confirmar que la clave es una clave Ed25519 y que OpenSSL es 1.1.1 o más reciente.
- Volver a ejecutar la llamada de firma.
- Relacionado. Referencia de excepciones.
Entrada: no se emitió el diccionario de marca de tiempo de archivo
Sección titulada «Entrada: no se emitió el diccionario de marca de tiempo de archivo»- Síntoma.
SignatureExceptioncon el finalno /Type /DocTimeStamp dictionary was emitted into the PDF buffer. - Causa probable. El bucle de archivado B-LTA se ejecutó, pero el diccionario de marca de tiempo del documento nunca llegó al búfer, por lo que el artefacto sería un B-LTA escrito parcialmente. El motor se niega a devolverlo.
- Evidencia / diagnóstico. La fábrica
SignatureException::documentTimestampNotEmitted()produce este mensaje. Es un fallo de poscondición lanzado en el momento de finalización. - Resolución.
- Dar la salida por descartada; no distribuir el artefacto parcial.
- Volver a ejecutar la canalización B-LTA con una autoridad de marca de tiempo accesible.
- Si el fallo se repite, capturar
getContext()y la excepción previa encadenada para un informe de defectos.
- Relacionado. Referencia de excepciones.
Casos límite y puntos delicados
Sección titulada «Casos límite y puntos delicados»- Estas fábricas fijan
cert_infoen un sujeto o una huella digital solo cuando está disponible; uncert_infovacío es esperable en los fallos de capacidad y de configuración. - Una solicitud B-LT o B-LTA sin un cliente HTTP configurado lanza
SignatureException::httpClientMissing(): la obtención de la revocación necesita un cliente PSR-18 proporcionado al orquestador. - Un certificado respaldado por un HSM sin una implementación de firmante lanza
SignatureException::hsmSignerMissing(); conectar el firmante al certificado antes de firmar.
Véase también
Sección titulada «Véase también»Glosario: nivel PAdES · aserción de revocación