Перейти к содержимому
getnextpdf.com

Ошибки безопасности и подписания

На этой странице описаны исключения домена безопасности в дереве пространства имён NextPDF\Security. Каждая запись называет класс, указывает, когда он генерируется, перечисляет поля, которые возвращает его getContext(), и даёт шаг восстановления.

Большинство этих классов наследуются от SecurityException, который наследуется от NextPdfException и реализует ContextAwareExceptionInterface. Это означает, что getContext(): array возвращает структурированную, не содержащую секретов диагностику, которую можно направить в конвейеры логирования или мониторинга производительности приложений (APM). Перехватывайте SecurityException, чтобы поймать любой сбой домена безопасности одним блоком; перехватывайте конкретный подкласс, когда вам нужна его типизированная полезная нагрузка.

Несколько классов в этом дереве наследуются напрямую от RuntimeException, а не от SecurityException. Они помечены ниже; они не предоставляют getContext(), и большинство из них задокументированы как внутренние сигналы потока управления, которые вы не должны ожидать перехватывать в коде приложения.

АспектПоведение
Базовый контрактNextPdfException::getContext() возвращает []; подклассы переопределяют его.
Гигиена секретовСообщения и контекст не содержат сырого ключевого материала, открытого текста, PIN-кодов и байтов вектора инициализации (IV). Ключи раскрываются только как префикс отпечатка.
SecurityExceptionАбстрактный базовый класс; не несёт собственных полей. Полезную нагрузку определяют подклассы.
  • Когда генерируется. Никогда не генерируется напрямую; это абстрактный базовый класс для домена безопасности. Он существует, чтобы один блок catch (SecurityException $e) мог поймать сбои целостности аутентифицированного шифрования, защиту от повторного использования nonce, привязку PDF/A к шифрованию, сбои управления ключами и сбои PKI.
  • Поля контекста. Собственных нет. Наследует пустую реализацию по умолчанию от NextPdfException; подклассы заполняют полезную нагрузку.
  • Восстановление. Перехватывайте конкретный подкласс для действенной обработки или SecurityException для грубой маршрутизации инцидентов безопасности.

Ошибки шифрования и аутентифицированного шифрования

Заголовок раздела «Ошибки шифрования и аутентифицированного шифрования»

Они генерируются шифратором AES-GCM (Galois/Counter Mode) и защитой PDF/A. Руководство «от симптома» см. в Шифровании и разрешениях.

  • Когда генерируется. Расшифровка с аутентифицированным шифрованием со связанными данными (AEAD) завершается сбоем по причине, не связанной с подделкой: усечённый шифротекст, отсутствующий IV или неверный ключ, переданный на границе API, где материала было недостаточно для фактического выполнения проверки целостности. Это ошибка конфигурации или транспорта, а не инцидент безопасности.
  • Поля контекста. algorithm (например AES-256-GCM), reason (например ciphertext shorter than IV+tag).
  • Восстановление. Убедитесь, что шифротекст, IV и ключ полны и правильно оформлены; не рассматривайте это как подделку. Сравните с TamperedDataException.
  • Когда генерируется. Тег аутентификации AEAD не проходит проверку. Тег покрывает шифротекст плюс связанные аутентифицированные данные (AAD); если что-либо из этого было изменено после шифрования, базовый openssl_decrypt() возвращает false. Этот отдельный подтип позволяет вам выдать оповещение уровня инцидента безопасности, а не ошибку оформления.
  • Поля контекста. algorithm, ciphertext_length (длина отклонённого шифротекста, исключая IV и тег).
  • Восстановление. Рассматривайте как подделку или неверный ключ/IV. Не повторяйте вслепую; расследуйте источник шифротекста. Согласно ISO/TS 32003:2023 §5.2 и NIST SP 800-38D §6.5, неудачная проверка тега означает, что данные не аутентичны.
  • Когда генерируется. AES-GCM просят зашифровать дважды с одной и той же парой ключ-IV. Шифратор защищается монотонным счётчиком на экземпляр и, как эшелонированная защита, хеш-множеством во время выполнения каждой выданной пары (отпечаток ключа, IV). Поскольку счётчик исключает коллизии по построению, это срабатывание — индикатор ошибки критического приоритета, которого никогда не должно происходить в продакшене. Повторное использование пары ключ/IV компрометирует весь поток ключа (ISO/TS 32003:2023 §5.2 NOTE 2; NIST SP 800-38D §8.3).
  • Поля контекста. key_fingerprint_prefix (первые 8 hex-символов SHA-256(key)), iv_length (всегда 12 для ISO/TS 32003), reason (hashset-collision или counter-rollover, различающие ломающую счётчик ошибку рефакторинга от триггера счётчика на 2^63), и iv_fixed_field_hex ( фиксированное поле IV, присутствует только при передаче, сообщается под собственным ключом и никогда не маркируется ошибочно как отпечаток ключа).
  • Восстановление. Немедленно прервите работу и смените ключ. Подайте отчёт о дефекте; это указывает на ошибку в шифраторе, а не на плохой ввод вызывающей стороны.
  • Когда генерируется. Достигнут необязательный счётчик вызовов безопасности использования NIST SP 800-38D §8.3 для данного ключа AES-GCM. Это телеметрический хук эшелонированной защиты для вызывающих сторон, желающих обеспечить рекомендованную спецификацией границу (около 2^32 вызовов на ключ) раньше архитектурных лимитов внутри шифратора. По умолчанию не срабатывает; только вспомогательный метод assertWithinSafetyBound() генерирует его.
  • Поля контекста. key_fingerprint_prefix, invocation_count (текущий счётчик encrypt(), на уровне лимита или выше), invocation_limit (необязательная граница).
  • Восстановление. Смените ключ документа (сконструируйте свежий шифратор с новым ключевым материалом), прежде чем накопленная вероятность коллизии и подделки перестанет быть пренебрежимо малой, или расширьте политику вызывающей стороны, чтобы отказать в дальнейшем обслуживании.
  • Когда генерируется. Предпринята попытка операции шифрования над документом с тегом PDF/A. Семейство PDF/A (PDF/A-2, PDF/A-3, PDF/A-4) единообразно запрещает шифрование: согласно ISO 19005 §6.1.3 ключ Encrypt не должен присутствовать в трейлере, и ISO 19005-4:2020 Приложения A и B наследуют это без изменений. Не существует допустимого сочетания PDF/A и шифрования.
  • Поля контекста. pdfa_mode (например pdfa4, pdfa3), encryption_operation (отклонённый вызов, например useAesGcm).
  • Восстановление. Чтобы создать зашифрованный документ, опустите вызов enablePdfA(); чтобы создать архивный документ, опустите вызов шифрования. См. Проверку PDF/A и PDF/UA.
  • Когда генерируется. Настроенная криптополитика отклоняет алгоритм, стойкость ключа или шифр, выбранный основной операцией подписания, шифрования или хеширования. Это граница с завершением при отказе для применения соответствия (например FIPS 140-2/3, eIDAS или пользовательской корпоративной политики), и она генерируется CryptoPolicyEnforcer до того, как будет создана какая-либо подпись или шифротекст, поэтому нарушающая политику операция никогда не сможет выдать неодобренный артефакт. Отличается от узкого сбоя операции OpenSSL и от сбоя примитива подписания: это отклонение политикой иначе допустимого запроса. Согласовано с NIST SP 800-131A Rev. 2 и ISO/IEC 19790:2025 §7.
  • Поля контекста. policy (имя политики, например FIPS 140-3 Strict), category (hash, signature, encryption или key-strength), item ( отклонённый элемент, например идентификатор объекта (OID), имя шифра или rsa/1024), reason.
  • Восстановление. Выберите алгоритм, длину ключа или шифр, которые одобряет названная политика, или скорректируйте политику, если она ваша. Направьте структурированный контекст в задокументированный регламент соответствия.

Существуют два одноимённых класса. Они разделяют корень SecurityException, поэтому один блок catch (SecurityException $e) ловит оба, но несут разные полезные нагрузки. Импортируйте по полностью квалифицированному имени, когда нужна конкретная форма.

KeyManagementException (жизненный цикл: NextPDF\Security\Exception)

Заголовок раздела «KeyManagementException (жизненный цикл: NextPDF\Security\Exception)»
  • Когда генерируется. Операция управления ключами завершается сбоем до того, как ключ потребляется примитивом подписания или шифрования: сбои разбора ключей Privacy-Enhanced Mail (PEM), PKCS#12 или PKCS#11; сбои вывода ключа (HKDF, PBKDF2, scrypt); отклонение AES Key Wrap (RFC 3394) при неверном ключе шифрования ключей; аппаратный модуль безопасности (HSM), возвращающий некорректные Distinguished Encoding Rules (DER); или несоответствие длины начального значения Ed25519.
  • Поля контекста. operation (например load_pem, kek_derive, key_wrap), key_type (например RSA, EC-P256, Ed25519, AES-256), reason. Сырой ключевой материал никогда не включается.
  • Восстановление. Изучите названную операцию и тип ключа, исправьте исходный ключевой материал или ввод для вывода ключа и повторите.

KeyManagementException (путь подписания: NextPDF\Security\Signature\Exception)

Заголовок раздела «KeyManagementException (путь подписания: NextPDF\Security\Signature\Exception)»
  • Когда генерируется. Провайдер подписи сталкивается с ошибкой управления ключами: запрошенная версия ключа неизвестна, отключена, запланирована к уничтожению, не имеет разрешения на подписание или иным образом непригодна. Именно это генерируют RsaPssSigner и LocalKeySignerProvider при сбоях с действующими ключами. Именованные конструкторы: unknownKeyVersion() и keyVersionDisabled().
  • Поля контекста. providerId, keyVersion, reason. Методы доступа: providerId(), keyVersion(), reason().
  • Восстановление. Смените или повторно выдайте разрешения для ключа, либо выберите пригодную версию ключа, затем повторите. Отличается от SignatureFailedException, который сигнализирует, что сам примитив подписания дал сбой.

Руководство «от симптома» по недостижимым уровням и отсутствующим возможностям см. в Сбоях подписи и метки времени.

  • Когда генерируется. Криптографическая операция подписания завершается сбоем: примитив подписания RSA, ECDSA или Ed25519 возвращает false или вывод неверной длины; HSM или токен PKCS#11 отвечает статусом, отличным от успешного; сборка SignedData Cryptographic Message Syntax (CMS) завершается сбоем на некорректном сертификате или цепочке; или не проходит самопроверка Ed25519 «туда и обратно». Новый код должен предпочитать этот подтип R4-13 устаревшему исключению подписи, связанному с PAdES.
  • Поля контекста. operation (например sign, verify, build_cms), algorithm (например rsa-pkcs1v15-sha256, ed25519), reason. Методы доступа: getOperation(), getAlgorithm(), getReason().
  • Восстановление. Прочтите операцию и алгоритм, исправьте ввод (ключ, цепочку сертификатов или доступность бэкенда) и повторите. Согласовано с посылкой работы с ключами «завершение при отказе» из ETSI EN 319 142-1.
  • Когда генерируется. Реализация SignerProviderInterface не может завершить операцию подписания по любой причине, не отнесённой к управлению ключами: ошибка драйвера бэкенда, некорректный ключевой материал или невосстановимый ввод-вывод HSM. Это тип-перехватчик всего для контракта подписания «завершение при отказе», где каждый примитив генерирует исключение при сбое, а не возвращает null, false или пустую строку. Именованный конструктор: forProvider().
  • Поля контекста. providerId, reason. Методы доступа: providerId(), reason().
  • Восстановление. Изучите идентификатор провайдера и причину, исправьте бэкенд провайдера или ключевой материал и повторите. Ветвитесь по KeyManagementException против этого типа, чтобы разделить «ключ плохой» от «примитив дал сбой».
  • Когда генерируется. Запрошенный уровень соответствия PAdES нельзя соблюсти в текущей инфраструктуре среды выполнения (чаще всего отсутствует служба меток времени для B-T и выше), а вызывающая сторона не предоставила разрешения на деградацию. По умолчанию поведение — завершение при отказе: движок отказывает, а не молча создаёт более низкий уровень, объявляя при этом более высокий, что было бы регрессией уровня eIDAS. Согласовано с ETSI EN 319 142-1 §6. Обратите внимание, что этот класс наследуется от NextPdfException напрямую (а не от SecurityException).
  • Поля контекста. requestedLevel, highestAchievableLevel, reason. Методы доступа: requestedLevel(), highestAchievableLevel(), reason().
  • Восстановление. Прочтите reason, чтобы определить отсутствующую инфраструктуру, и предоставьте её (например, настройте службу меток времени), или передайте allowDegradation: true в PadesOrchestrator, чтобы намеренно принять наивысший достижимый уровень.
  • Когда генерируется. У SignerProviderRegistry::get() запрашивают идентификатор провайдера, который не зарегистрирован. Реализует PSR-11 NotFoundExceptionInterface, поэтому реестр соответствует контракту контейнера PSR-11. Именованный конструктор: forId(). Этот класс наследуется от RuntimeException и не предоставляет getContext().
  • Поля контекста. Нет. Незарегистрированный идентификатор появляется в сообщении.
  • Восстановление. Зарегистрируйте провайдер под ожидаемым идентификатором перед его запросом или исправьте идентификатор, который вы передаёте реестру.

Они наследуются от RuntimeException и не предоставляют getContext(). SHAKE256 — это расширяемая выходная функция SHA-3, требуемая некоторыми путями ISO/TS 32001.

  • Когда генерируется. Во время вычисления дайджеста, когда выбранный провайдер не может удовлетворить запрос. Именованные конструкторы: noBackend() (нет работающего бэкенда SHAKE256 на этом хосте по всем испробованным уровням) и ffiCallFailed() (FFI-привязанный вызов OpenSSL EVP вернул статус, отличный от успешного, например из урезанной сборки libcrypto).
  • Поля контекста. Нет. Сообщение называет испробованные уровни или сбойный символ.
  • Восстановление. Установите ext-ffi с присутствующим OpenSSL 3.x или обновитесь до сборки PHP, которая предоставляет shake256 в hash_algos(). Пользовательский запасной вариант Keccak намеренно не поставляется.
  • Когда генерируется. Из конструктора провайдера SHAKE256, когда зонд возможностей завершается неудачно, поэтому провайдер не может быть инстанцирован. Это сигнал потока управления: реестр провайдеров перехватывает его, записывает метку уровня и пробует следующий уровень. Он никогда не должен попадать в код приложения. Именованный конструктор: forTier().
  • Поля контекста. Нет. Сообщение называет уровень и причину.
  • Восстановление. Напрямую не действенно для вызывающей стороны; если вся цепочка уровней исчерпана, реестр вместо этого выдаёт Shake256NotAvailableException::noBackend(), который несёт исправление, ориентированное на оператора.

Они охватывают код аутентификации сообщения (MAC) уровня документа ISO/TS 32004, хранящийся под /AuthCode. Оба наследуются от NextPdfException и переопределяют getContext().

  • Когда генерируется. С завершением при отказе, читателем MAC-токена, когда MAC-токен CMS AuthenticatedData структурно некорректен или объявляет алгоритм вне согласованного набора ISO/TS 32004. Именованные конструкторы: malformed() и algorithmMismatch(). Помечен @internal.
  • Поля контекста. status (значение DocumentMacVerificationStatus, либо MalformedToken, либо AlgorithmMismatch). Публичное свойство readonly: $status.
  • Восстановление. Считайте документ непроверенным. Некорректный токен или алгоритм вне согласованного набора означает, что MAC не может установить доверие; не продолжайте так, как будто содержимое защищено.
  • Когда генерируется. С завершением при отказе, когда проверка MAC уровня документа не может достичь доверенного состояния: отсутствующий или некорректный /AuthCode, алгоритм вне согласованного набора, сбой развёртывания или несоответствие MAC (подделка). Метод verify() верификатора возвращает явный результат для ветвления; это аналог в потоке исключений, генерируемый assertVerified(), чтобы код «доверять содержимому» никогда не мог продолжиться за непроверенным документом. Именованный конструктор: fromResult().
  • Поля контекста. status (значение DocumentMacVerificationStatus). Публичное свойство readonly: $status.
  • Восстановление. Не доверяйте содержимому документа. Изучите status, чтобы отличить подделку (несоответствие MAC) от проблемы конфигурации (отсутствующий или некорректный /AuthCode, несоответствие алгоритма).

Они охватывают проверку пути сертификации RFC 5280. Базовый тип и его подклассы завершаются при отказе.

  • Когда генерируется. Сбой строгого режима от валидатора пути RFC 5280. Это неконечный базовый класс для более узких подклассов (ChainLengthExceededException, UnsupportedExtensionException), поэтому обработчики, перехватывающие этот тип, также перехватывают их по принципу подстановки Лисков. Наследуется от SecurityException.
  • Поля контекста. Не переопределяет getContext() (наследует пустую реализацию по умолчанию). Несёт структурированные причины в замороженном публичном свойстве-массиве readonly $reasons (непустой список строк из имени правила и описания).
  • Восстановление. Прочтите $reasons, чтобы определить сбойное правило, исправьте цепочку сертификатов и проверьте повторно. Перехватывайте этот тип, чтобы единообразно обрабатывать любой сбой проверки пути.
  • Когда генерируется. Валидатор пути просят обойти цепочку, длина которой превышает настроенный предел. Ограничение применяется до начала любого разбора, поэтому злонамеренный поставщик не может загнать валидатор в квадратичную работу или исчерпать ресурсы произвольно глубокой цепочкой. Предел по умолчанию в 10 следует профилю PKIX-CMP (RFC 4210 §5.3.18); реальные цепочки умещаются в 5–6 записей. Подкласс PkiPathValidationException.
  • Поля контекста. Наследует пустую getContext(); строка причины chain_length_exceeded: supplied=<n> cap=<n> передаётся в родительский $reasons. Публичные свойства readonly: $supplied, $cap.
  • Восстановление. Предоставьте цепочку в пределах предела или повысьте настроенное ограничение, если ожидается законная более длинная цепочка.
  • Когда генерируется. Валидатор пути встречает критическое расширение X.509, чьё применение ещё не реализовано. Согласно RFC 5280 §4.2, нераспознанное критическое расширение должно завершаться отказом; и строгий, и мягкий режимы здесь завершаются отказом, поскольку молчаливый пропуск критического расширения был бы регрессией безопасности. Валидатор охватывает построение цепочки, сопоставление AKI/SKI, использование ключа, расширенное использование ключа, базовые ограничения, истечение срока и проверку подписи; всё иное критическое проявляется здесь. Подкласс PkiPathValidationException.
  • Поля контекста. Наследует пустую getContext(); структурированные причины передаются в родительский $reasons. Публичные свойства readonly: $extensionOid (точечный OID, например 2.5.29.30 для ограничений имён), $extensionName, $clauseRef (указатель на пункт RFC 5280 и запись в журнале отложенных элементов).
  • Восстановление. В мягком режиме перехватывайте этот конкретный подкласс, чтобы откатиться к более грубой политике, не проглатывая реальные сбои проверки пути. Сверьте $extensionOid и $clauseRef с вашими фикстурами PKI, чтобы увидеть, какое расширение блокирует проверку.
  • Когда генерируется. И конечные точки OCSP, и списка отзыва сертификатов (CRL) исчерпаны без окончательного вердикта: сбой транспорта OCSP или некорректный ответ, и сбой транспорта CRL или некорректный CRL, при этом оба предохранителя открыты или оба кеша отсутствуют. Строгий режим рассматривает это как завершение при отказе; мягкий режим перехватывает это и выдаёт предупреждение PSR-3 с revocation = null. Наследуется от SecurityException.
  • Поля контекста. Не переопределяет getContext() (наследует пустую реализацию по умолчанию). Несёт состояние в публичных свойствах readonly $ocspState и $crlState (каждое по умолчанию unknown).
  • Восстановление. Восстановите доступность источника отзыва, дождитесь закрытия предохранителей или прогрейте кеш, затем повторите. Не подавляйте это ради получения артефакта долгосрочной проверки; утверждение об отзыве является частью этого уровня.
  • Когда генерируется. Подпись BasicOCSPResponse по RFC 6960 §4.2.2.2 не проходит криптографическую проверку относительно сертификата ответчика. Парсер декодирует signatureAlgorithm (RSA-PSS, ECDSA или RSA-PKCS1v15) и проверяет signature над tbsResponseData; любой сбой генерирует это типизированное исключение, чтобы вызывающие стороны могли отличить структурно корректный, но криптографически подделанный ответ от ответа с некорректным DER. Неконечный, поэтому пакеты ниже по потоку могут публиковать более специфичные подклассы. Наследуется от SecurityException.
  • Поля контекста. Не переопределяет getContext() (наследует пустую реализацию по умолчанию). Несёт тег сбоя в публичном свойстве readonly $reason (например signature_mismatch, responder_cert_not_in_bundle, unsupported_signature_algorithm); свободнотекстовая detail встроена в сообщение.
  • Восстановление. Изучите $reason. Для responder_cert_not_in_bundle предоставьте правильный набор якорей доверия и сертификат ответчика. Для signature_mismatch считайте ответ ненадёжным. См. Сбои подписи и метки времени.
  • Когда генерируется. Сбой связи со службой меток времени (TSA) RFC 3161 или разбора ответа: TSA возвращает статус ошибки, HTTP-запрос завершается сбоем или ответ ASN.1 не удаётся разобрать. Это база иерархии сбоев TSA и она неконечна, чтобы сбои проверки могли её расширять. Наследуется от NextPdfException.
  • Поля контекста. Не переопределяет getContext() (наследует пустую реализацию по умолчанию).
  • Восстановление. Перехватывайте TsaException для любого пути сбоя TSA. Проверьте доступность TSA и то, что конечная точка возвращает корректно сформированный ответ RFC 3161.
  • Когда генерируется. Проверка CMS токена TimeStampToken RFC 3161 завершается сбоем на любом из обязательных шагов проверки: привязка ESSCertIDv2 по RFC 5816 §3, целостность подписанных атрибутов по RFC 5652 §11, свежесть producedAt по RFC 3161 §2.4.2 или подпись SignerInfo по RFC 5652 §5.4. С завершением при отказе и типизированным дискриминатором шага, чтобы конвейеры аудита могли отличить повтор от расхождения часов и несоответствия сертификата без grep-поиска по сообщениям. Подкласс TsaException, поэтому устаревшие обработчики catch (TsaException) продолжают срабатывать.
  • Поля контекста. step (сбойное значение Step конвейера) и message. Метод доступа: getStep().
  • Восстановление. Действенно для разработчика (неправильно настроенный сертификат TSA или допуск расхождения) или для безопасности (подозрение на MITM или повтор). Прочтите step, чтобы локализовать сбойный этап и исправить соответствующий ввод или конфигурацию доверия.
  • Когда генерируется. Внутренний сигнал о том, что обход DER достиг некорректной или усечённой границы, генерируемый низкоуровневыми обходчиками внутри верификатора токена TSA. Он всегда перехватывается на публичной границе проверки и переоборачивается в TsaTokenVerificationException, несущий правильный дискриминатор шага; он никогда не утекает в код вызывающей стороны. Наследуется от RuntimeException; помечен @internal.
  • Поля контекста. Нет.
  • Восстановление. Не обращён к вызывающей стороне. Обрабатывайте вместо этого обёрнутое TsaTokenVerificationException.

Они наследуются от RuntimeException и не предоставляют getContext(). Оба являются декодерами с завершением при отказе.

  • Когда генерируется. Декодер ограничений имён встречает применимый элемент GeneralSubtree, который не может достоверно декодировать. RFC 5280 §4.2.1.10 требует, чтобы доверяющая сторона обработала применимое ограничение имени или отклонила сертификат; преобразование прежнего молчаливого отбрасывания в этот типизированный сбой предотвращает завершение при пропуске, которое молча расширило бы принятый набор имён. Область ограничена применимыми формами имён (directoryName, dNSName, iPAddress, rfc822Name, uniformResourceIdentifier); неприменимые формы остаются игнорируемыми и никогда его не генерируют. Именованный конструктор: undecodableEnforceableBase(). Помечен @internal.
  • Поля контекста. Нет. Строка детали, безопасная для журнала, несётся в сообщении.
  • Восстановление. Применитель выдаёт причину name_constraints: с завершением при отказе, и цепочка отклоняется. Исследуйте кодировку ограничений имён сертификата; не ослабляйте применение.
  • Когда генерируется. Расширение qcStatements структурно некорректно: усечённый DER, неверный тег или переполнение длины. Декодер завершается при отказе и генерирует исключение, а не возвращает частичный или эвристический результат, когда не может достоверно определить, что говорит расширение. Помечен @api.
  • Поля контекста. Нет.
  • Восстановление. Перехватывайте его явно, только если намерены терпеть некорректную кодировку; иначе считайте утверждения квалифицированного сертификата неопределимыми и отклоните или перевыпустите сертификат.
  • Когда генерируется. Дефект управления сеансом PKCS#11 v3.1. Каждый именованный конструктор сопоставлен с конкретным классом дефекта и с возвращаемым значением PKCS#11 CKR_*, раскрытым через типизированный дискриминатор $kind, чтобы вызывающие стороны ветвились по стабильной enum-строке вместо хрупкого сопоставления по сообщениям. Конструкторы включают: cryptokiNotInitialized(), userNotLoggedIn(), userAlreadyLoggedIn(), operationNotInitialized(), operationActive(), mechanismNotAllowed(), tokenDisconnected(), concurrentSessionLimitExceeded(), sessionAlreadyClosed(), stateTransitionInvalid(), osLockingRequired(), loginTtlExpired() и signOperationTtlExpired(). Наследуется от SecurityException.
  • Поля контекста. Не переопределяет getContext() (наследует пустую реализацию по умолчанию). Несёт типизированный вид в публичном свойстве readonly $kind, одну из констант KIND_* (например KIND_USER_NOT_LOGGED_IN, KIND_TOKEN_DISCONNECTED, KIND_LOGIN_TTL_EXPIRED). Идентификаторы слота и сеанса, механизм и значения TTL появляются в сообщении. PIN-коды и байты сертификата никогда не включаются.
  • Восстановление. Переключайтесь по $kind. Для user_not_logged_in войдите с пользовательским PIN-кодом перед инициализацией операции подписания. Для token_disconnected считайте все сеансы на слоте осиротевшими. Для видов TTL пройдите повторную аутентификацию или переинициализируйте операцию. Для mechanism_not_allowed расширьте настроенный список разрешённых механизмов или выберите разрешённый механизм.