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

Enterprise редакция

Security — глубокий справочник (HSM, PKCS#11, режим FIPS)

Эта страница — объединённый углублённый справочник по поверхности безопасности NextPDF Enterprise. Она охватывает подписание аппаратным токеном по PKCS#11, подписание в подпроцессе через интерфейс командной строки OpenSSL (CLI), предустановки криптополитики FIPS, страж FIPS во время выполнения и страж самопроверки при включении. Существуют два узконаправленных дополнения: HSM — углублённый справочник для деталей подписывающего модуля и FIPS 140 — углублённый справочник для деталей модуля FIPS. Путь постквантового подписания — это предварительная версия без заявления о соответствии. NextPDF не имеет сертификации и не предоставляет её; поддержка не равна соответствию, а соответствие не равно сертификации.

Эта возможность поставляется в составе NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без этого права не загружает классы возможности. Сравните редакции и получите лицензию.

Окно терминала
composer require nextpdf/enterprise:^3

Типы подписания находятся в NextPDF\Enterprise\Security\Signature\Hsm; типы FIPS находятся в NextPDF\Enterprise\Security\Fips; корень композиции находится в NextPDF\Enterprise\Bootstrap. Оба подписывающих модуля реализуют контракт Core NextPDF\Contracts\HsmSignerInterface. Политика реализует контракты Core NextPDF\Contracts\CryptoPolicyInterface и NextPDF\Contracts\PreOperationalSelfTestInterface.

СимволПараметрыПоведение по умолчаниюВозвращаетБросает или падает сПримечания
Pkcs11Signer::__construct()string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = nullОткрывает библиотеку поставщика, выполняет вход в слот, загружает метаданные сертификата и алгоритма ключаHsmOperationException, когда ext-pkcs11 отсутствует или доступ к токену не удаётсяPIN и метки — #[SensitiveParameter]; один хэндл модуля кешируется на каждый путь библиотеки на процесс
Pkcs11Signer::isAvailable()НетСообщает, загружено ли ext-pkcs11boolНетСтатический; проверяйте перед конструированием
Pkcs11Signer::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Подписывает на токене; сырой вывод ECDSA преобразуется в DER ECDSA-Sig-Valuestring — сырые байты подписиHsmOperationException (ключ не найден, сбой токена); InvalidArgumentException (несопоставленный алгоритм); FipsViolationException / FipsModuleErrorStateException до подписания, когда подключён enforcerЗакрытый набор алгоритмов; см. раздел «Контракт поведения»
Pkcs11Signer::signPqs()string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = trueОтклоняется, если не установлен $enablePostQuantum; вызывает предварительный постквантовый механизм PKCS#11string — сырые байты подписиHsmOperationException (отключено, сбой токена, несоответствие длины подписи); InvalidArgumentException (контекст более 255 байт)Предварительная версия; без заявления о соответствии
Pkcs11Signer — поверхность аксессоровНетРезультаты конструирования только для чтенияbool / string / array<string>НетisPostQuantumEnabled, getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm
OpenSslCliSigner::__construct()string $keyUri, string $certPath, string $pin, array $extraCertPaths = [], OpenSslCliBackend $backend = OpenSslCliBackend::Auto, string $opensslBinary = 'openssl', int $timeoutSeconds = 30, ?string $modulePath = null, ?string $configPath = null, bool $legacyPinDelivery = false, ?FipsSignatureEnforcer $fipsEnforcer = nullПроверяет proc_open, зондирует бинарник, разрешает бэкенд, загружает сертификатыHsmOperationException (proc_open отключён, отсутствует файл модуля/конфигурации/сертификата, нет бэкенда); InvalidArgumentException (pin-value внутри $keyUri)Auto предпочитает провайдер OpenSSL 3.x, затем engine
OpenSslCliSigner::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Подписывает в подпроцессе openssl; PIN по умолчанию передаётся через временный файл-источник PIN с правами 0600string — сырые байты подписиHsmOperationException (таймаут, PIN отклонён, ключ не найден, пустой вывод); InvalidArgumentException (несопоставленный алгоритм); исключения гейта FIPS до подписанияПодпроцесс завершается по истечении $timeoutSeconds; stderr редактируется
OpenSslCliSigner — поверхность аксессоровНетРезультаты конструирования только для чтенияstring / array<string> / OpenSslCliBackendНетgetCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion
OpenSslCliBackendEnum: Provider, Engine, AutoНетВыбор бэкенда для CLI-подписывающего модуля
Pkcs11PqsAlgorithmEnum наборов параметров ML-DSA и SLH-DSAНетВспомогательные методы: isMlDsa, isSlhDsa, mechanismId, parameterSetId, signatureLength, nistCategory
PqsCapabilityStatus::current()НетФормирует честное постквантовое состояние для процессаPqsCapabilityStatusНетКаждый булев признак заявления о соответствии жёстко задан как false; ни один флаг не может его включить
HsmSignerProviderAdapterHsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15Представляет конкретную реализацию HSM как единый SignerProviderInterfaceСогласно SPIKeyManagementException (версия ключа не null); SignatureFailedException (сбой драйвера, пустая подпись)Идентификаторы провайдеров: pkcs11-{module-id}, openssl-cli
HsmOperationExceptionТипизированный сбой для каждого пути подписания HSMРасширяет Core NextPdfException
FipsCryptoPolicy::strict() / ::standard()?FipsSelfTest $selfTest = nullФабричные предустановки; strict — профиль FIPS 140-3, standard добавляет AES-128-CBCFipsCryptoPolicyНетНеизменяемые списки разрешений; см. Поведение в режиме FIPS
FipsCryptoPolicy — поверхность предикатовВходы string / intПроверки принадлежности списку разрешенийbool / stringНетisHashAlgorithmAllowed, isSignatureAlgorithmAllowed, isEncryptionAlgorithmAllowed, isKeyStrengthAllowed, getPreferredHashAlgorithm, getName
FipsCryptoPolicy::assertPreOperational()НетВыполняет (или воспроизводит) самопроверку при включенииvoidFipsModuleErrorStateExceptionУправляется швом принуждения Core при первой криптографической операции
FipsModeGuard::__construct()CryptoPolicyInterface $policy, ?FipsBootGuard $bootGuard = null, ?FipsAuditLogger $auditLogger = nullОборачивает политику границами в стиле assertНетБез загрузочного стража гейт самопроверки отсутствует (только политика)
FipsModeGuard — поверхность assertВходы string / intСначала каталог запретов, затем список разрешений; запись аудита перед любым бросаниемvoidFipsViolationException; FipsModuleErrorStateException (подключён загрузочный страж)assertHashAllowed, assertSignatureAlgorithmAllowed, assertEncryptionAllowed, assertKeyStrengthAllowed, а также getPolicy
FipsBootGuard::report() / ::rerun()НетВыполняет батарею самопроверки (кешированную / принудительную)FipsSelfTestReportНетОтчёт ERROR фиксирует процесс; успешный повторный запуск никогда не снимает фиксацию
FipsBootGuard::assertOperational()НетУтверждает, что модуль OPERATIONALvoidFipsModuleErrorStateExceptionЛипкое: зафиксированный в процессе ERROR отклоняет даже чистый экземпляр
FipsBootGuard::status()НетСообщает кешированный статусFipsSelfTestStatusНетPRE_OPERATIONAL, OPERATIONAL или ERROR
FipsSelfTest::run()НетВыполняет полную батарею тестов с известным ответом; никогда не завершается досрочноFipsSelfTestReportНетКонструктор принимает внедряемые провайдеры хеша и случайных байтов для детерминированных тестов
FipsSelfTestReport / FipsSelfTestResult / FipsSelfTestStatusОбъекты-значения отчёта и enum статусаFipsSelfTestReport::assertOperational() бросает FipsModuleErrorStateExceptionresults всегда перечисляет каждый результат в качестве доказательства для аудита
FipsSignatureEnforcer::assertSignatureGenerationAllowed()string $algorithm, string $certificatePemРазрешает OID подписи и стойкость ключа, затем делегирует стражуvoidFipsViolationException (запрещено или неклассифицируемо, защита от отказа)Узкое место, которое оба подписывающих модуля вызывают в начале sign() в режиме FIPS
FipsAuditLoggerCryptoPolicyInterface $policy, LoggerInterface $loggerИспускает записи ALLOW (INFO) / DENY (WARNING) на каждое решениеbool на каждый вызов логированияНетlogHashOperation, logSignatureOperation, logEncryptionOperation, logKeyStrengthCheck
FipsTransitioningAlgorithmsВходы string / intСтатический каталог запретов NIST SP 800-131Abool / arrayНетСлой явных запретов под каждой границей стража
FipsBootstrap::boot() / ::lazy()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = nullКомпонует загрузочный страж, политику и страж режима; boot() выполняет самопроверку сразу, lazy() откладывает её до первой границыFipsModeGuardboot(): FipsModuleErrorStateException при неуспешном тестеПо умолчанию использует строгую политику
FipsBootstrap::signatureEnforcer()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = nullЗагружает модуль и возвращает гейт времени генерации для подписывающих модулейFipsSignatureEnforcerFipsModuleErrorStateExceptionПередайте результат в параметр $fipsEnforcer подписывающего модуля
FipsBootstrap::selfTestReport()?FipsSelfTest $selfTest = nullВыполняет батарею по требованию и подводит итогarray{status, operational, failed}НетПредназначено для конечных точек проверки состояния и подкоманды CLI
FipsViolationException / FipsModuleErrorStateExceptionТипизированные сбои FIPSПредоставляют policyName / violatingItem / reason и failedResults соответственно
public function __construct(private readonly string $libraryPath, private readonly int $slotId, #[SensitiveParameter] private readonly string $pin, #[SensitiveParameter] private readonly string $certLabel, #[SensitiveParameter] private readonly ?string $keyLabel = null, array $chainDer = [], private readonly bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null)
public static function isAvailable(): bool
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): string
public function __construct(private string $keyUri, string $certPath, #[SensitiveParameter] private string $pin, array $extraCertPaths = [], private OpenSslCliBackend $backend = OpenSslCliBackend::Auto, private string $opensslBinary = 'openssl', private int $timeoutSeconds = 30, private ?string $modulePath = null, private ?string $configPath = null, private bool $legacyPinDelivery = false, private ?FipsSignatureEnforcer $fipsEnforcer = null)
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public static function strict(?FipsSelfTest $selfTest = null): self
public static function standard(?FipsSelfTest $selfTest = null): self
public function assertPreOperational(): void
public function __construct(private CryptoPolicyInterface $policy, private ?FipsBootGuard $bootGuard = null, private ?FipsAuditLogger $auditLogger = null)
public function assertHashAllowed(string $algorithm): void
public function assertSignatureAlgorithmAllowed(string $oid): void
public function assertEncryptionAllowed(string $algorithm): void
public function assertKeyStrengthAllowed(string $keyType, int $bitLength): void
public function getPolicy(): CryptoPolicyInterface
public static function boot(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function lazy(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function signatureEnforcer(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null): FipsSignatureEnforcer
public static function selfTestReport(?FipsSelfTest $selfTest = null): array
  • Разрешение контрактов. Оба подписывающих модуля реализуют Core HsmSignerInterface; политика реализует Core CryptoPolicyInterface. Вызывающий код зависит от контрактов, поэтому обновление редакции меняет композицию, а не места вызовов.
  • Хранение ключа. Закрытый ключ никогда не покидает границу токена. Pkcs11Signer делегирует операцию токену; OpenSslCliSigner передаёт подпроцессу ссылку на ключ в виде URI PKCS#11. NextPDF не хранит, не генерирует и не гарантирует безопасность ключа подписи. Защита ключа — это обязанность оператора по его хранению (NIST SP 800-57 Part 1 Rev.5 §5.5.2).
  • Сессия и вход. Операция подписания токена, сессия и вход пользователя следуют PKCS#11 v3.1 §5. Метка сертификата и метка закрытого ключа могут различаться; конструктор принимает отдельную метку ключа для таких токенов.
  • Закрытый набор алгоритмов. Подписывающие модули принимают ровно: RSA PKCS#1 v1.5 с SHA-256/384/512, RSASSA-PSS с SHA-256/384/512 и ECDSA с SHA-256/384/512 (Pkcs11Signer также принимает ecdsa-raw). Любой другой идентификатор вызывает InvalidArgumentException; никогда не подписывается алгоритм-заместитель.
  • Привязка соли PSS. Для каждого варианта PSS длина соли равна длине дайджеста — 32, 48 или 64 байта — и параметры хеша и генерации маски соответствуют выбранному дайджесту (PKCS#11 v3.1 §5).
  • Преобразование ECDSA. Механизмы ECDSA токена возвращают сырую подпись; sign() преобразует её в форму ECDSA-Sig-Value с DER-кодировкой для совместимости с PDF и OpenSSL. Генерация подписи следует FIPS 186-5 §6.3.2.
  • Содержимое предустановок. Строгая предустановка разрешает SHA-256/384/512; OID подписей RSA и ECDSA с этими хешами; RSASSA-PSS; AES-256-CBC и AES-256-GCM; минимум RSA 2048 и EC 256. Стандартная предустановка дополнительно разрешает AES-128-CBC для совместимости со старыми системами. Любое использование AES-GCM требует уникального вектора инициализации для каждого ключа (NIST SP 800-38D §5).
  • Двухслойное принуждение. Каждая граница стража сначала сверяется с явным каталогом запретов NIST SP 800-131A, затем со списком разрешений политики. Слой запретов формирует однозначный для аудита сигнал «запрещено»; список разрешений остаётся авторитетным.
  • Самопроверка при включении. Батарея охватывает SHA-256/384/512, HMAC-SHA-256, AES-256-CBC, AES-256-GCM, тест попарной согласованности ECDSA P-256 и проверку состояния генератора случайных битов. Первая криптографическая операция под управлением политики на пути Core выполняет её один раз на процесс, с защитой от отказа. Сбой переводит модуль в состояние ERROR; криптографические службы отклоняются до сброса. Это следует ISO/IEC 19790:2025 §7.10, §7.10.2, §7.10.3 и §7.10.3.p3.
  • Липкое состояние ERROR. Обнаруженный ERROR фиксируется на весь процесс. Конструирование новой политики или загрузочного стража не отмывает его; успешный повторный запуск не снимает его. Только перезапуск процесса — настоящий цикл питания — сбрасывает состояние.
  • Только гейт генерации. FipsSignatureEnforcer управляет созданием новых подписей. Проверка ранее существующих подписей — это устаревшее использование и никогда не проходит через enforcer.
  • Аудиторский след. Когда страж скомпонован с логгером аудита, каждая граница испускает запись ALLOW или DENY до разрешения или отклонения операции. Логгер сверяется с той же политикой, которую принуждает страж, поэтому записанное решение не может разойтись.
  • Конструирование Pkcs11Signer без ext-pkcs11 немедленно вызывает HsmOperationException; расширение не входит в стандартные дистрибутивы PHP.
  • Метка сертификата или закрытого ключа, не соответствующая ни одному объекту токена, вызывает HsmOperationException с указанием отсутствующего класса объекта.
  • OpenSslCliSigner отклоняет $keyUri, содержащий pin-value, при конструировании, с защитой от отказа; вместо этого PIN передаётся через безопасный путь источника PIN.
  • В режиме FIPS идентификатор алгоритма, который не может быть сопоставлен с известным OID подписи, отклоняется с защитой от отказа; так же и сертификат, стойкость открытого ключа которого не может быть определена.
  • Неизвестный тип ключа отклоняется по умолчанию; политика никогда не откатывается к более слабому алгоритму.
  • Неуспешный тест с известным ответом вызывает FipsModuleErrorStateException, несущее неуспешные результаты; каждая последующая граница в процессе повторяет сбой до перезапуска.
  • Страж, сконструированный без загрузочного стража, принуждает списки разрешений, но не предоставляет гейт самопроверки; рабочая композиция FIPS предоставляет его через bootstrap.
  • signPqs() отказывается выполняться, если не установлено согласие в конструкторе. Строка контекста более 255 байт вызывает InvalidArgumentException (FIPS 204 §5.4). Возвращённая подпись, длина в байтах которой не соответствует выбранному набору параметров, отклоняется до того, как достигнет кодирования.

Разрешено в FIPS в строгом режиме: SHA-256/384/512; RSA PKCS#1 v1.5 и RSA-PSS с этими хешами; ECDSA с этими хешами; AES-256-CBC и AES-256-GCM; RSA не менее 2048 бит, EC не менее 256 бит. Отклоняется в FIPS в строгом режиме: более слабые или устаревшие хеши, неодобренные OID подписей, AES-128 (разрешён только в стандартной предустановке) и любой ключ ниже минимальной стойкости. Минимальная длина ключа RSA и статус перехода следуют NIST SP 800-131A Rev.2 §3. Сочетание кривой и хеша ECDSA следует FIPS 186-5 §6.1.1. Путь защищён от отказа и никогда не подставляет более слабый алгоритм.

NextPDF Enterprise не является криптографическим модулем, валидированным по FIPS, и не делает заявления о сертификации FIPS. NextPDF Enterprise работает в FIPS-совместимом режиме только тогда, когда настроен с валидированным по FIPS криптопровайдером — например, валидированным по FIPS провайдером OpenSSL — или валидированным по FIPS HSM. Политика режима FIPS способствует соответствию; это не сертификация. В этом репозитории нет артефакта сертификации FIPS.

ЗаявлениеСтандартПункт
Семантика операции подписания токена, сессии и входа пользователяPKCS#11 v3.1§5 (sign)
Длина соли PSS равна длине дайджестаPKCS#11 v3.1§5 (PSS sLen)
Генерация подписи ECDSA; сочетание кривой и хешаFIPS 186-5§6.3.2; §6.1.1
Минимальная длина ключа RSA и статус перехода генерации подписиNIST SP 800-131A Rev.2§3
Категория самопроверки, документация, условный триггер, непересекающееся множествоISO/IEC 19790:2025§7.10, §7.10.2, §7.10.3, §7.10.3.p3
Уникальность вектора инициализации AES-GCMNIST SP 800-38D§5
Ответственность за защиту и хранение ключаNIST SP 800-57 Part 1 Rev.5§5.5.2
Строка контекста постквантового подписания ограничена 255 байтамиFIPS 204§5.4

Все пункты изложены в пересказе; нормативный текст не воспроизводится. Это заявления о возможностях кода NextPDF, а не сертификации. Проверяется ли созданная подпись — это решение проверяющей стороны на основе её собственной конфигурации доверия. Политика режима FIPS — это функция содействия соответствию, а не юридическое заключение; обращайтесь к собственным консультантам по комплаенсу и праву. Этот модуль касается криптографической функциональности; относитесь к нему как к чувствительному для безопасности в собственном обзоре.

  • Компонуйте режим FIPS через bootstrap: boot() для гейта при запуске, lazy() для откладывания батареи до первой границы и фабрику enforcer для параметра $fipsEnforcer подписывающих модулей. Развёртывания без FIPS передают null, и поведение не меняется.
  • Подкоманда fips:self-test в bin/nextpdf-enterprise выполняет батарею по требованию и завершается с ненулевым кодом в состоянии ERROR; подключите её к заданиям обслуживания или конечным точкам проверки состояния только для администратора (самопроверки по требованию ISO/IEC 19790:2025).
  • FipsBootGuard::resetProcessErrorLatchForTesting()@internal и только для тестов; рабочий код никогда её не вызывает, поскольку это нарушило бы липкое состояние ERROR.
  • Конструируйте подписывающие модули один раз и переиспользуйте их; конструирование выполняет вход и читает сертификат, а кеш модуля на каждую библиотеку делает повторное конструирование для той же библиотеки безопасным.
  • Предоставляйте PIN из менеджера секретов. Это #[SensitiveParameter], никогда не логируется и не сериализуется; не фиксируйте его в конфигурации.
  • Оператор владеет провижинингом токена, обработкой PIN, конфигурацией слота, сетевой защитой сетевого HSM и настройкой доверия. Эта страница не раскрывает внутренние детали политики PIN токена или материал учётных данных поставщика.
  • Не включайте постквантовую предварительную версию для рабочих подписей AdES. Каталог криптографических наборов AdES пока не признаёт постквантовые наборы, большинство просмотрщиков PDF отклоняют такие подписи, а сквозная проверка на оборудовании не завершена. Внутренние детали механизмов остаются во внутренней документации исходного репозитория и выходят за рамки этого руководства.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую поверхность публичного API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов выходят за рамки.