Enterprise редакция
Подписание через аппаратный модуль безопасности (PKCS#11)
NextPDF Enterprise подписывает PDF ключом, хранящимся внутри аппаратного модуля безопасности (HSM). Вы указываете подписанту токен PKCS#11 — смарт-карту, токен Universal Serial Bus (USB) или сетевой HSM — и операция подписания выполняется на устройстве. Закрытый ключ никогда не покидает границу токена. Эта страница описывает поведение: что делает подписант, что предоставляете вы и где хранение ключей перестаёт быть ответственностью NextPDF.
Подписант HSM разрешается через контракт подписанта Core, поэтому ваше приложение зависит от контракта, а не от конкретного типа Enterprise. Он расширяет тот же путь подписания Cryptographic Message Syntax (CMS), что использует Core, за исключением того, что криптографическая операция делегируется токену.
Предварительные требования указаны во фронтматтере и повторены в разделе Предварительные требования, чтобы вы не были застигнуты врасплох посреди задачи.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без этого права не загружает классы возможности. Сравнить редакции и получить лицензию.
NextPDF Core поставляет программный подписант CMS, который держит ключ в процессе или принимает его через контракт стратегии подписания Core; NextPDF Pro добавляет удалённые и облачные стратегии подписания key-management-service (KMS). Аппаратное хранение ключей через PKCS#11 — это возможность Enterprise, не предоставляемая Core или Pro.
Что делает эта возможность
Заголовок раздела «Что делает эта возможность»Токен PKCS#11 предоставляет криптографические объекты — сертификаты и закрытые ключи — за разделяемой библиотекой производителя. Подписант Enterprise адаптирует эту библиотеку:
- Он открывает разделяемую библиотеку токена один раз на процесс и кэширует дескриптор модуля, потому что PKCS#11 требует, чтобы модуль был инициализирован ровно один раз на процесс.
- Он открывает сессию на настроенном слоте и входит в систему с предоставленным PIN. Вход аутентифицирует пользователя до любой операции с закрытым ключом, согласно PKCS#11 v3.1 §5.6.8.
- Он находит сертификат подписания на токене по метке, читает сертификат в форме Distinguished Encoding Rules (DER) и определяет алгоритм открытого ключа.
- Во время подписания он находит закрытый ключ по метке — которая на некоторых токенах может отличаться от метки сертификата — и просит токен вычислить подпись. Данные для подписи передаются внутрь; ключ остаётся на устройстве.
Подписант поддерживает RSA с дополнением PKCS#1 v1.5 (SHA-256, SHA-384, SHA-512), RSA с дополнением Probabilistic Signature Scheme (PSS), где длина соли равна длине дайджеста, и Elliptic Curve Digital Signature Algorithm (ECDSA) с SHA-256, SHA-384 и SHA-512. Кривая ECDSA и дайджест сопоставляются по соглашению — P-256 с SHA-256, P-384 с SHA-384, P-521 с SHA-512 — следуя рекомендуемому сопоставлению в RFC 5480. Токен возвращает подпись ECDSA как сырую конкатенацию двух целых чисел; подписант преобразует её в форму с кодировкой DER, которую ожидают PDF и OpenSSL.
Для генерации подписи ключ RSA не менее 2048 бит и порядок кривой ECDSA не менее 224 бит — это приемлемые минимумы согласно NIST SP 800-131A Rev.2 §3. Подготавливайте ключ токена с такими размерами или выше.
Существует альтернативный путь через движок OpenSSL для токенов с поддержкой движка. В OpenSSL 3.x расширение OpenSSL для PHP не предоставляет интерфейс прикладного программирования (API) движка, поэтому класс движка устарел; поддерживаемый маршрут с движком запускает командно-строчный бинарник OpenSSL. Предпочитайте прямой путь PKCS#11 там, где у вашего токена есть библиотека PKCS#11.
Почему это устроено именно так
Заголовок раздела «Почему это устроено именно так»Несущее решение состоит в том, что закрытый ключ никогда не покидает токен. Поэтому подписант делегирует криптографическую операцию устройству и переносит через шов PKCS#11 только данные для подписи. Он никогда не читает и не восстанавливает ключевой материал в памяти PHP. Он разрешается через контракт Core HsmSignerInterface, а не через конкретный тип Enterprise, поэтому код подписания одинаков независимо от того, живёт ли ключ в программном обеспечении, в облачном KMS или в аппаратном токене. Он кэширует дескриптор модуля один раз на процесс, потому что PKCS#11 инициализирует каждый модуль ровно один раз на процесс, а затем преобразует сырой вывод ECDSA токена в DER, чтобы валидаторы видели ожидаемую кодировку. Форму определяет хранение, а не удобство: граница доверия остаётся на краю устройства.
Фоновая информация о проектировании: Подписание с опорой на HSM.
Предварительные требования
Заголовок раздела «Предварительные требования»Прежде чем подписывать с HSM, подтвердите каждый пункт:
- Установите NextPDF Core и пакет Enterprise:
composer require nextpdf/core:^3иcomposer require nextpdf/enterprise. - Держите активную лицензию NextPDF Enterprise; разрешайте пакет относительно учётных данных вашей лицензии на Private Packagist.
- Установите разделяемую библиотеку PKCS#11 производителя токена на хост (например,
.soв Linux или.dllв Windows) и запишите её абсолютный путь, номер слота и метки объектов. - Загрузите расширение PHP
ext-pkcs11. Оно не входит в стандартный PHP и должно устанавливаться отдельно. Конструктор подписанта вызывает типизированную ошибку операции, когда расширение отсутствует.
Конфигурация
Заголовок раздела «Конфигурация»Предоставьте подписанту эти входные данные:
- Путь к библиотеке — абсолютный путь к разделяемой библиотеке PKCS#11 производителя.
- Идентификатор слота — номер слота токена, обычно
0. - PIN — PIN токена. Считайте его секретом: предоставляйте из менеджера секретов, а никогда из исходного кода или журналов. Подписант помечает параметр PIN конфиденциальным, поэтому он исключён из трассировок стека и сериализации.
- Метка сертификата — метка объекта сертификата на токене.
- Метка ключа — метка объекта закрытого ключа, когда она отличается от метки сертификата.
- Цепочка — опциональные промежуточные сертификаты в форме DER, когда токен их не хранит.
Проверяйте доступность токена до конструирования подписанта. Конструирование читает сертификат с токена, поэтому неправильно настроенный слот или метка дают быстрый сбой с типизированной ошибкой, а не во время подписания.
Пошагово
Заголовок раздела «Пошагово»- Подтвердите, что среда выполнения поддерживает PKCS#11, проверив доступность расширения. Не конструируйте подписанта, когда расширение отсутствует.
- Прочитайте PIN из менеджера секретов в переменную, которая никогда не логируется.
- Сконструируйте подписанта HSM с путём к библиотеке, слотом, PIN и метками. Конструирование входит в систему и читает сертификат.
- Передайте подписанта оркестратору подписания Core через
HsmSignerInterface. Оркестратор вычисляет диапазон байтов, строит подписанные атрибуты CMS, передаёт данные токену и собирает подписанный PDF. - Перехватите наиболее конкретный сбой, залогируйте структурное сообщение без PIN и перевыбросите исключение.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;
/** * Build a hardware-token signer only when the runtime supports it. * * The concrete PKCS#11 signer is resolved through the Core contract so the * caller depends on the interface, not the Enterprise implementation type. * The PIN arrives from a secret resolver; it is never written to source. * * @param callable(): bool $pkcs11Available Reports ext-pkcs11 availability. * @param callable(): HsmSignerInterface $signerFactory Builds the configured token signer. * * @throws \RuntimeException When the PKCS#11 extension is not loaded. * * @return HsmSignerInterface The token signer, ready for the Core orchestrator. */function resolveHsmSigner(callable $pkcs11Available, callable $signerFactory): HsmSignerInterface{ if ($pkcs11Available() !== true) { throw new \RuntimeException( 'PKCS#11 signing requires the ext-pkcs11 extension; install it before signing.', ); }
return $signerFactory();}Продакшн-связка — точный список аргументов конструктора и типы типизированных исключений — описана в подробном справочнике по HSM.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;use NextPDF\Exception\NextPdfException;use Psr\Log\LoggerInterface;
final readonly class HsmSigningService{ public function __construct( private HsmSignerInterface $signer, private LoggerInterface $logger, ) {}
/** * Sign data on the token through the Core HSM contract. * * The byte range is computed by the engine, never accepted from the * caller. The token performs the signing operation; the private key * does not leave the device. * * @param string $data The bytes the orchestrator hands to the token. * @param string $algorithm The OpenSSL-style signing algorithm identifier. * * @throws NextPdfException When the token operation fails. * * @return string The raw signature bytes returned by the token. */ public function sign(string $data, string $algorithm): string { try { return $this->signer->sign($data, $algorithm); } catch (NextPdfException $e) { // Structural message only — never the PIN or key material. $this->logger->error('HSM signing failed', ['reason' => $e->getMessage()]);
throw $e; } }}Проверка
Заголовок раздела «Проверка»Подтвердите результат так, как это сделал бы верификатор:
- Считайте обратно сертификат подписанта и цепочку в форме DER от подписанта и убедитесь, что они совпадают с сертификатом, подготовленным на токене.
- Откройте подписанный PDF в валидаторе, настроенном с вашими якорями доверия, и убедитесь, что подпись сообщается как криптографически целостная. Созданная подпись — это не проверенная подпись; решение о доверии принадлежит верификатору и его якорям доверия, а не производителю.
- Для подписи ECDSA убедитесь, что встроенная подпись имеет кодировку DER — подписант преобразует сырой вывод токена за вас, поэтому валидатор, отклоняющий форму сырой конкатенации, всё равно должен принять встроенную подпись.
- Убедитесь, что в журналах вашего приложения не появляется ни PIN, ни метка токена, ни ключевой материал.
Безопасность и соответствие
Заголовок раздела «Безопасность и соответствие»- Ключ остаётся на токене. Данные для подписи передаются токену; операция подписания выполняется внутри границы токена. Закрытый ключ никогда не загружается в память PHP.
- PIN — это секрет. Это конфиденциальный параметр конструктора, исключённый из журналов и сериализации. Предоставляйте его из менеджера секретов. Повторная неудачная повторная аутентификация может заблокировать PIN на токене; политику обеспечивает токен, а не NextPDF.
- Fail-closed. Ошибка токена или HSM вызывает типизированное исключение. Подписант не создаёт неподписанный или частично подписанный результат и никогда не подставляет более слабый алгоритм.
- Стойкость алгоритма. Подготавливайте ключи RSA не менее 2048 бит и кривые ECDSA с порядком не менее 224 бит — приемлемые минимумы для генерации подписи согласно NIST SP 800-131A Rev.2 §3.
- Постквантовое подписание экспериментально и по умолчанию выключено. Постквантовый путь существует за явным флагом включения. Стандартные долгосрочные архивные профили PDF Advanced Electronic Signatures (PAdES) пока не распознают постквантовые наборы, и большинство программ просмотра отклоняют их при проверке. Не включайте его для продакшн-подписей PAdES.
Эта страница касается криптографического подписания и интеграции с аппаратным модулем безопасности. Каждый нормативный источник приведён в пересказе; нормативный текст не воспроизводится. ### Граница хранения ключей
NextPDF Enterprise интегрируется с токеном PKCS#11 или HSM. Он не хранит, не генерирует и не гарантирует безопасность ключа подписания. Безопасность ключа зависит от токена или HSM, от развёртывания и от оператора — а не только от NextPDF Enterprise. Вы отвечаете за подготовку токена, обработку PIN, настройку слота и сетевую защиту сетевого HSM.
Обработка сбоев
Заголовок раздела «Обработка сбоев»- Расширение отсутствует. Конструирование подписанта PKCS#11 вызывает типизированное исключение операции, когда
ext-pkcs11не загружено. Сначала проверьте доступность. - Сертификат или ключ не найден по метке. Конструирование или подписание вызывает типизированное исключение, называющее недостающий объект. Подтвердите метку и слот.
- Уже выполнен вход. Когда несколько экземпляров подписанта разделяют кэшированный модуль для одного слота, подписант выходит из системы и входит снова, чтобы обеспечить свежую проверку PIN — это требуется токенам персональной идентификации с политикой «PIN каждый раз».
- Неподдерживаемый алгоритм. Запрос алгоритма, который подписант не сопоставляет, вызывает ошибку аргумента, а не подписание с подстановкой.
- Сетевой HSM недостижим. Сетевая ошибка или ошибка устройства вызывает типизированное исключение; подписант никогда тихо не создаёт неподписанный документ.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов находятся вне области рассмотрения.
См. также
Заголовок раздела «См. также»- Подписание HSM — справочник — подробный справочник по подписанту PKCS#11.
- Security — NextPDF Enterprise — объединённая поверхность безопасности Enterprise.
- Signature — NextPDF Enterprise — долгосрочный производитель PAdES B-LT и B-LTA.
- Криптополитика FIPS 140 — политика режима FIPS и барьер самопроверки.
- Подписание через облачный KMS — NextPDF Pro — стратегии key-management-service для AWS, Azure и GCP.
- Security / Signing (Core) — подписант CMS Core и контракт стратегии подписания.
- HSM · PKCS#11 · CMS · ECDSA — термины глоссария.