Устранение неполадок: ошибки подписи и метки времени
Область применения
Заголовок раздела «Область применения»В этих записях описаны сбои подписи, которые проявляются как NextPDF\Exception\SignatureException и NextPDF\Security\Signature\Exception\SignatureLevelUnreachableException. Каждая запись указывает точный фабричный метод или класс, поэтому вы можете подтвердить причину по сообщению и getContext(), а не строить догадки.
Примечание о формулировках. Движок не подтверждает, что подпись действительна или документ защищён. Он сообщает об обнаруженном сбое. Рассматривайте каждое решение как шаг по устранению указанной причины.
Запись: уровень PAdES “B-LT” или “B-LTA” не может быть создан
Заголовок раздела «Запись: уровень PAdES “B-LT” или “B-LTA” не может быть создан»- Симптом.
SignatureExceptionс окончанием сообщенияnextpdf/enterprise package is required for B-LT/B-LTA signatures. - Вероятная причина. Отсутствует поставщик возможностей долгосрочной проверки. B-LT и B-LTA встраивают данные об отзыве и архивную метку времени; этот поставщик входит в
nextpdf/enterprise. - Свидетельство / диагностика. Фабричный метод
SignatureException::ltvCapabilityMissing()генерирует именно это сообщение.getContext()возвращаетsignature_levelсо значением уровня, который вы пытались задать. - Решение.
- Установите поставщик, выполнив
composer require nextpdf/enterprise. - Повторите вызов подписания.
- Если установить поставщик нельзя, запросите вместо этого
B-BилиB-T, которые может создать пакет core.
- Установите поставщик, выполнив
- См. также. Справочник по исключениям.
Запись: уровень подписи недостижим, и вызов отклоняется
Заголовок раздела «Запись: уровень подписи недостижим, и вызов отклоняется»- Симптом.
SignatureLevelUnreachableExceptionс сообщением в формеPAdES level "<x>" is unreachable (highest achievable: "<y>"). - Вероятная причина. Запрошенный уровень соответствия требует инфраструктуру, недоступную во время подписания, чаще всего службу меток времени для B-T и выше. Движок завершает операцию отказом: не понижает уровень молча и не заявляет более высокий уровень.
- Свидетельство / диагностика.
getContext()возвращаетrequestedLevel,highestAchievableLevelиreason. Полеreasonуказывает, какой инфраструктуры не хватает. Это поведение по умолчанию с завершением при отказе: оно не допускает выпуск документа с заявленным уровнем, которому документ не соответствует. - Решение.
- Проверьте поле
reason, чтобы определить отсутствующую инфраструктуру. - Подключите отсутствующий компонент. Например, настройте службу меток времени и снова выполните вызов.
- Если нужно намеренно принять более низкий уровень, передайте
allowDegradation: trueвPadesOrchestrator. Тогда вызов создастhighestAchievableLevelи сообщит созданный уровень.
- Проверьте поле
- См. также. Шифрование и разрешения.
Запись: требуется клиент службы меток времени, но он отсутствует
Заголовок раздела «Запись: требуется клиент службы меток времени, но он отсутствует»- Симптом.
SignatureExceptionс окончаниемTSA client is required for level <x> but none was provided. - Вероятная причина. Для запроса B-T, B-LT или B-LTA нужен клиент службы меток времени, а у оркестратора его нет.
- Свидетельство / диагностика. Фабричный метод
SignatureException::tsaRequired()генерирует это сообщение;getContext()содержит запрошенныйsignature_level. - Решение.
- Настройте клиент службы меток времени и передайте его оркестратору.
- Повторите вызов.
- Чтобы создать уровень, не требующий метки времени, запросите
B-B.
- См. также. Справочник по исключениям.
Запись: URL-адрес конечной точки службы меток времени пуст
Заголовок раздела «Запись: URL-адрес конечной точки службы меток времени пуст»- Симптом.
SignatureExceptionс окончаниемTSA endpoint URL is empty. - Вероятная причина. Клиент службы меток времени был создан с пустым URL-адресом конечной точки.
- Свидетельство / диагностика. Фабричный метод
SignatureException::tsaUrlEmpty()генерирует это сообщение. Это ошибка конфигурации, а не сетевой сбой. - Решение.
- Задайте на клиенте службы меток времени непустой URL-адрес конечной точки, например
https://timestamp.example.com/tsa. - Если для запрошенного уровня метка времени не нужна, вместо этого удалите привязку клиента службы меток времени.
- Повторите вызов.
- Задайте на клиенте службы меток времени непустой URL-адрес конечной точки, например
- См. также. Справочник по исключениям.
Запись: в буфере отсутствует заполнитель подписи
Заголовок раздела «Запись: в буфере отсутствует заполнитель подписи»- Симптом.
SignatureExceptionс окончаниемno /Contents <…> field found in PDF buffer (signature placeholder missing). - Вероятная причина. Этап подписания получил буфер без зарезервированного контейнера подписи, поэтому ему некуда записать подпись.
- Свидетельство / диагностика. Фабричный метод
SignatureException::signatureContentsNotFound()генерирует это сообщение. - Решение.
- Убедитесь, что поле подписи и заполнитель для него записаны до запуска этапа подписания.
- Перезапустите конвейер, чтобы заполнитель существовал к моменту начала подписания.
- См. также. Справочник по исключениям.
Запись: статус отзыва неизвестен (ответчик OCSP отклонил запрос)
Заголовок раздела «Запись: статус отзыва неизвестен (ответчик OCSP отклонил запрос)»- Симптом.
SignatureExceptionс окончаниемOCSP responder returned non-successful OCSPResponseStatus "<status>". - Вероятная причина. Ответчик Online Certificate Status Protocol (OCSP) не вернул статус
successful, поэтому не предоставил утверждение об отзыве. В исходном коде движок ссылается на RFC 6960 §4.2.1: заполненное тело ответа допускается только для статусаsuccessful (0). Отклонённый ответ движок не считает положительным результатом с точки зрения доверия. - Свидетельство / диагностика. Фабричный метод
SignatureException::nonSuccessfulOcspResponseStatus()генерирует это сообщение и указывает полученный статус, напримерtryLaterилиinternalError. Если байт статуса зарезервирован или неизвестен, вместо этого срабатываетSignatureException::reservedOcspResponseStatus(). - Решение.
- Посмотрите статус в сообщении. Для временного статуса вроде
tryLaterповторите запрос на получение данных об отзыве позже. - Для
unauthorizedилиmalformedRequestпроверьте URL-адрес запроса OCSP и сертификат, ожидаемый ответчиком. - Не подавляйте сбой при получении артефакта B-LT или B-LTA; утверждение об отзыве является частью этого уровня.
- Посмотрите статус в сообщении. Для временного статуса вроде
- См. также. Справочник по исключениям.
Запись: запись цепочки сертификатов не декодируется
Заголовок раздела «Запись: запись цепочки сертификатов не декодируется»- Симптом.
SignatureExceptionс окончаниемfailed to base64-decode PEM body — input is not valid PEM. - Вероятная причина. Запись цепочки сертификатов не соответствует корректному формату Privacy-Enhanced Mail (PEM), обычно из-за усечения, постороннего символа или двоичного блока Distinguished Encoding Rules (DER), переданного там, где ожидался PEM.
- Свидетельство / диагностика. Фабричный метод
SignatureException::pemDecodingFailed()генерирует это сообщение во время сборки цепочки. - Решение.
- Проверьте каждый сертификат цепочки на наличие посторонних символов или усечения.
- Повторно экспортируйте затронутый сертификат в формате PEM.
- Повторите вызов подписания.
- См. также. Шифрование и разрешения.
Запись: тип закрытого ключа не соответствует алгоритму
Заголовок раздела «Запись: тип закрытого ключа не соответствует алгоритму»- Симптом.
SignatureExceptionс окончаниемexpected private key of type "<x>" for the configured algorithm but got "<y>". - Вероятная причина. Загруженный закрытый ключ не соответствует настроенному алгоритму подписи, например, ключ Rivest-Shamir-Adleman (RSA) при выборе Elliptic Curve Digital Signature Algorithm (ECDSA).
- Свидетельство / диагностика. Фабричный метод
SignatureException::unexpectedKeyType()генерирует это сообщение и указывает как ожидаемый, так и фактический класс ключа. - Решение.
- Убедитесь, что сертификат и пара ключей соответствуют выбранному алгоритму.
- Измените выбор алгоритма так, чтобы он соответствовал ключу, или загрузите ключ, соответствующий алгоритму.
- Повторите вызов подписания.
- См. также. Справочник по исключениям.
Запись: ключ или материал подписи Ed25519 имеет неверный формат
Заголовок раздела «Запись: ключ или материал подписи Ed25519 имеет неверный формат»- Симптом.
SignatureExceptionс окончанием, указывающим на несоответствие длины Ed25519: например,Ed25519 signature length <n> ≠ expected 64 bytesилиEd25519 round-trip self-verify failed. - Вероятная причина. Криптографическая среда выполнения вернула ключ или материал подписи неверной длины, либо только что созданная подпись не проверяется собственным открытым ключом. В исходном коде движок ссылается на RFC 8032 §3.4, где длина отсоединённой подписи Ed25519 зафиксирована как 64 байта. Движок прерывает работу, а не выдаёт материал, который не может самостоятельно проверить.
- Свидетельство / диагностика. Соответствующие фабричные методы:
SignatureException::ed25519SignatureMalformed(),::ed25519RoundTripVerifyFailed(),::ed25519KeyParseFailed(),::ed25519SeedInvalid(),::ed25519SecretKeyMalformed()и::ed25519PublicKeyInvalid(). Каждый указывает наблюдаемую длину. - Решение.
- Переустановите PHP-расширение libsodium; урезанная или повреждённая сборка задокументирована как причина появления материала неверной длины.
- Убедитесь, что ключ относится к Ed25519 и используется OpenSSL версии 1.1.1 или новее.
- Повторите вызов подписания.
- См. также. Справочник по исключениям.
Запись: словарь архивной метки времени не был выведен
Заголовок раздела «Запись: словарь архивной метки времени не был выведен»- Симптом.
SignatureExceptionс окончаниемno /Type /DocTimeStamp dictionary was emitted into the PDF buffer. - Вероятная причина. Архивный цикл B-LTA выполнился, но словарь метки времени документа так и не попал в буфер. Артефакт был бы недописанным B-LTA, поэтому движок отказывается его возвращать.
- Свидетельство / диагностика. Фабричный метод
SignatureException::documentTimestampNotEmitted()генерирует это сообщение. Это нарушение постусловия возникает на этапе финализации. - Решение.
- Считайте вывод отброшенным; не поставляйте частичный артефакт.
- Перезапустите конвейер B-LTA с доступной службой меток времени.
- Если сбой повторяется, зафиксируйте
getContext()и связанное предыдущее исключение для отчёта о дефекте.
- См. также. Справочник по исключениям.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Эти фабричные методы задают
cert_infoв виде субъекта или отпечатка только тогда, когда он доступен; пустоеcert_infoожидаемо для сбоев возможностей и конфигурации. - Запрос B-LT или B-LTA без настроенного клиента Hypertext Transfer Protocol (HTTP) вызывает
SignatureException::httpClientMissing(); для получения данных об отзыве оркестратору нужно передать клиент PHP Standards Recommendation (PSR)-18. - Сертификат, который опирается на аппаратный модуль безопасности (HSM), но не имеет реализации подписывающего компонента, вызывает
SignatureException::hsmSignerMissing(); перед подписанием привяжите подписывающий компонент к сертификату.
См. также
Заголовок раздела «См. также»Глоссарий: уровень PAdES · утверждение об отзыве