Enterprise edycja
Podpisywanie HSM — szczegółowa referencja
W skrócie
Dział zatytułowany „W skrócie”Ta strona to dogłębna dokumentacja powierzchni podpisywania HSM w NextPDF Enterprise. Obejmuje trzy publiczne typy. NextPDF\Enterprise\Security\Signature\Hsm\Pkcs11Signer podpisuje przez token PKCS#11 za pośrednictwem rozszerzenia ext-pkcs11. NextPDF\Enterprise\Security\Signature\Hsm\OpenSslCliSigner podpisuje przez binarium openssl w podprocesie, dla kluczy opartych na dostawcy lub silniku, których PHP ext-openssl nie potrafi wczytać. NextPDF\Enterprise\Security\Signature\Hsm\Provider\HsmSignerProviderAdapter udostępnia każdy z konkretnych typów jako ujednolicony SignerProviderInterface. Na każdej ścieżce klucz prywatny pozostaje wewnątrz granicy tokenu; NextPDF przekazuje bajty do podpisania i otrzymuje podpis. Ścieżka post-kwantowa (signPqs) to podgląd: jest domyślnie wyłączona, nie niesie żadnego oświadczenia o zgodności i nie ma obsługiwanej ścieżki weryfikacji w obecnych walidatorach PDF. NextPDF nie posiada żadnej certyfikacji ani żadnej nie udziela; wsparcie nie równa się zgodności, a zgodność nie równa się certyfikacji.
Dostępność i licencjonowanie
Dział zatytułowany „Dostępność i licencjonowanie”Ta funkcja jest dostarczana w NextPDF Enterprise (nextpdf/enterprise) i aktywuje się wraz z kopertą licencji poziomu Enterprise. Wdrożenie bez tego uprawnienia nie wczytuje klas tej funkcji. Porównaj edycje i uzyskaj licencję.
Powierzchnia publicznego API
Dział zatytułowany „Powierzchnia publicznego API”Wszystkie trzy typy znajdują się w NextPDF\Enterprise\Security\Signature\Hsm; adapter mieści się w jego podprzestrzeni nazw Provider. Oba sygnatariusze implementują kontrakt Core NextPDF\Contracts\HsmSignerInterface.
| Symbol | Parametry | Zachowanie domyślne | Zwraca | Rzuca lub kończy się niepowodzeniem z | Uwagi |
|---|---|---|---|---|---|
Pkcs11Signer::__construct() | string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null | Otwiera bibliotekę dostawcy, loguje się do slotu i wczytuje z tokenu certyfikat oraz metadane algorytmu klucza | — | HsmOperationException, gdy brakuje ext-pkcs11 lub dostęp do tokenu zawodzi | Jeden uchwyt modułu jest buforowany na ścieżkę biblioteki na proces; PIN i etykiety mają #[SensitiveParameter] |
Pkcs11Signer::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Podpisuje na tokenie; surowe wyjście ECDSA jest konwertowane do DER ECDSA-Sig-Value | string surowe bajty podpisu | HsmOperationException (klucz nieznaleziony, awaria tokenu); InvalidArgumentException (niezmapowany algorytm); wyjątki bramki FIPS przed podpisaniem, gdy podłączony jest enforcer | Zamknięty zbiór algorytmów; zobacz Kontrakt zachowania |
Pkcs11Signer::signPqs() | string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true | Odrzucane, o ile nie ustawiono $enablePostQuantum; wysyła prowizoryczny mechanizm PQ PKCS#11 | string surowe bajty podpisu | HsmOperationException (wyłączone, awaria tokenu, niezgodność długości podpisu); InvalidArgumentException (kontekst powyżej 255 bajtów) | Podgląd; brak oświadczenia o zgodności; identyfikatory mechanizmu są prowizoryczne |
Pkcs11Signer::isPostQuantumEnabled() | Brak | Zgłasza flagę opt-in z konstruktora | bool | Brak | — |
Pkcs11Signer::getCertificateDer() | Brak | Zwraca certyfikat sygnatariusza odczytany z tokenu | string (DER) | Brak | Wczytywany raz przy konstrukcji |
Pkcs11Signer::getCertificateChainDer() | Brak | Zwraca pośrednie certyfikaty dostarczone przez konstruktor | array<string> (DER) | Brak | Wyklucza certyfikat sygnatariusza |
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 | Weryfikuje proc_open, sonduje binarium i wersję, rozwiązuje backend oraz wczytuje certyfikaty | — | HsmOperationException (proc_open wyłączone, brak pliku modułu/konfiguracji/certyfikatu, awaria binarium, brak backendu); InvalidArgumentException (pin-value wewnątrz $keyUri) | OpenSslCliBackend::Auto preferuje dostawcę OpenSSL 3.x, następnie silnik |
OpenSslCliSigner::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Uruchamia openssl dgst w podprocesie; PIN domyślnie wędruje przez efemeryczny plik pin-source 0600 | string surowe bajty podpisu | HsmOperationException (timeout, PIN odrzucony, klucz nieznaleziony, awaria wczytania modułu, puste wyjście, awaria pliku pin); InvalidArgumentException (niezmapowany algorytm); wyjątki bramki FIPS przed podpisaniem | Podproces jest ubijany po $timeoutSeconds; stderr jest redagowany, zanim trafi do komunikatów |
Powierzchnia akcesorów OpenSslCliSigner | Brak | Tylko do odczytu wyniki konstrukcji | string / array<string> / OpenSslCliBackend | Brak | getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion |
HsmSignerProviderAdapter::__construct() | HsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15 | Opakowuje konkret HSM jako SignerProviderInterface | — | Brak | Konwencje id dostawcy: pkcs11-{module-id}, openssl-cli |
HsmSignerProviderAdapter::providerId() | Brak | Zwraca id dostarczone przez konstruktor | non-empty-string | Brak | — |
HsmSignerProviderAdapter::supportsAlgorithm() | SignatureAlgorithm $algo | Mapuje enum na nazwę w stylu OpenSSL, następnie przecina ze zbiorem dozwolonym backendu | bool | Brak | Odrzuca algorytmy typu digest-only; identyfikatory openssl-engine nie rozgłaszają niczego |
HsmSignerProviderAdapter::sign() | string $data, ?string $keyVersion = null | Wysyła przez opakowany sygnatariusz z konfigurowanym algorytmem | non-empty-string | KeyManagementException (niepuste $keyVersion); SignatureFailedException (niemapowalny algorytm, awaria sterownika, pusty podpis) | Kontrakt SPI fail-closed; każdy błąd sterownika wypływa typowany |
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 function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): stringpublic function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): stringpublic function isPostQuantumEnabled(): boolpublic function getCertificateDer(): stringpublic function getCertificateChainDer(): arraypublic 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'): stringpublic function getCertificateDer(): stringpublic function getCertificateChainDer(): arraypublic function getPublicKeyAlgorithm(): stringpublic function getCertificatePem(): stringpublic function getResolvedBackend(): OpenSslCliBackendpublic function getOpensslVersion(): stringpublic function __construct(private HsmSignerInterface $hsm, private string $providerId, private SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15)public function providerId(): stringpublic function supportsAlgorithm(SignatureAlgorithm $algo): boolpublic function sign(string $data, ?string $keyVersion = null): stringKontrakt zachowania
Dział zatytułowany „Kontrakt zachowania”- Piecza nad kluczem. Klucz prywatny nigdy nie opuszcza granicy tokenu.
Pkcs11Signerdeleguje operację do tokenu;OpenSslCliSignerprzekazuje referencję klucza — URI PKCS#11 — do podprocesuopenssl. Żaden z sygnatariuszy nie potrafi wyeksportować klucza. - Sesja i logowanie.
Pkcs11Signerbuforuje jeden uchwyt modułu PKCS#11 na ścieżkę biblioteki na proces, ponieważ interfejs tokenu musi zostać zainicjalizowany dokładnie raz na proces. Każda operacja otwiera sesję i loguje się PIN-em; logowanie uwierzytelnia użytkownika przed jakimkolwiek użyciem klucza prywatnego (PKCS#11 v3.1 §5.6.8). Gdy slot zgłasza istniejące logowanie, sygnatariusz wylogowuje się i loguje ponownie, aby tokeny wymagające świeżego PIN-u na operację go otrzymały. - Zbiór algorytmów (zamknięty). Oba sygnatariusze akceptują dokładnie:
sha256WithRSAEncryption,sha384WithRSAEncryption,sha512WithRSAEncryption;RSASSA-PSS,RSASSA-PSS-SHA256,RSASSA-PSS-SHA384,RSASSA-PSS-SHA512;ecdsa-with-SHA256,ecdsa-with-SHA384,ecdsa-with-SHA512.Pkcs11Signerdodatkowo akceptujeecdsa-raw. Każdy inny identyfikator wywołujeInvalidArgumentException— żaden algorytm zastępczy nigdy nie jest podpisywany. - Wiązanie soli PSS. Dla każdego wariantu PSS długość soli równa się długości skrótu — 32, 48 lub 64 bajty — a parametry hash i MGF pasują do wybranego skrótu. Wynika to ze struktury parametrów mechanizmu PSS, gdzie długość soli to zazwyczaj długość skrótu wiadomości (PKCS#11 v3.1 §6.1.9). Oba sygnatariusze stosują to samo parowanie, więc konfiguracja poprawna na jednym backendzie jest poprawna na drugim.
- Konwersja ECDSA. Token zwraca podpis ECDSA jako surową, dopełnioną zerami konkatenację r i s (PKCS#11 v3.1 §6.3.1).
Pkcs11Signer::sign()konwertuje to wyjście do zakodowanej w DER postaciECDSA-Sig-Value, której oczekują walidatory PDF oraz OpenSSL. Wywołujący nigdy nie ma do czynienia z postacią surową. - Dostarczanie PIN-u (ścieżka CLI). W bezpiecznym trybie domyślnym PIN jest zapisywany do efemerycznego pliku utworzonego wyłącznie z uprawnieniami tylko dla właściciela, wskazywany przez atrybut
pin-sourcew URI PKCS#11 i usuwany po zakończeniu podprocesu. W tym trybie PIN nie jest umieszczany w wierszu poleceń ani eksportowany do środowiska podprocesu. Przy$legacyPinDelivery = truePIN jest osadzony jakopin-valuew URI, co jest obserwowalne w wierszu poleceń procesu; ten tryb jest wyłącznie opt-in. - Dyscyplina podprocesu.
OpenSslCliSigneruruchamia binarium z tablicą argumentów — bez interpolacji powłoki — wymusza$timeoutSeconds, ubija podproces po wygaśnięciu i klasyfikuje stderr do typowanych błędów. Sekrety są redagowane ze stderr, zanim zostanie zacytowany w komunikacie wyjątku. - Semantyka adaptera. Token HSM nie ma koncepcji zarządzanej wersji klucza; kluczem na tokenie jest wersja.
HsmSignerProviderAdapter::sign()odrzuca zatem każde niepuste$keyVersionzKeyManagementException, zamiast je ignorować.supportsAlgorithm()przecina mapowanie enum z akceptowanym zbiorem opakowanego backendu, więc adapter nigdy nie rozgłasza mechanizmu, który backend odrzuciłby w czasie podpisu. Pusty podpis ze sterownika wywołujeSignatureFailedException. - Podgląd post-kwantowy.
signPqs()jest bramkowane flagą konstruktora$enablePostQuantumi w innym przypadku odmawia uruchomienia. Ciąg kontekstu jest ograniczony do 255 bajtów, co odpowiada granicy kontekstu ML-DSA (FIPS 204). Zwrócony podpis musi zgadzać się z dokładną długością bajtową wybranego zestawu parametrówPkcs11PqsAlgorithm, w przeciwnym razie wywołanie zawodzi. Identyfikatory mechanizmu podążają za prowizorycznym rozszerzeniem PQ PKCS#11 i nie są ostateczne. Profile PAdES nie rozpoznają zestawów post-kwantowych, większość walidatorów PDF odrzuca takie podpisy, a NextPDF nie zapewnia dla nich ścieżki weryfikacji. Nie jest deklarowana żadna zgodność.
Przypadki brzegowe i tryby awarii
Dział zatytułowany „Przypadki brzegowe i tryby awarii”- Skonstruowanie
Pkcs11Signerbezext-pkcs11wywołujeHsmOperationExceptionnatychmiast; to rozszerzenie nie jest dołączane do standardowych dystrybucji PHP. - Etykieta certyfikatu lub klucza prywatnego, która nie pasuje do żadnego obiektu na tokenie, wywołuje
HsmOperationExceptionnazywający brakującą klasę obiektu. Etykieta klucza może na niektórych tokenach zgodnie z prawem różnić się od etykiety certyfikatu. - Powtarzające się nieudane logowania mogą zablokować PIN na tokenie; to token egzekwuje tę politykę, nie NextPDF. Tokeny, których klucze wymagają uwierzytelnienia przy każdym użyciu, otrzymują świeże logowanie przez ścieżkę wylogowania i ponowienia (PKCS#11 v3.1, semantyka always-authenticate).
OpenSslCliSignerodrzuca przy konstrukcji$keyUri, który już zawierapin-value, fail-closed, ponieważ takie dostarczenie ominęłoby bezpieczną ścieżkę PIN-u.- W systemie Windows bezpieczny tryb pliku pin kończy się niepowodzeniem fail-closed z
HsmOperationException: bity uprawnień pliku nie mogą tam ograniczyć nadań odczytu ACL, więc sygnatariusz odmawia pozostawienia PIN-u w postaci jawnej na ACL katalogu tymczasowego. Starsze dostarczanie PIN-u jest udokumentowaną, opcjonalną alternatywą dla zaufanych hostów Windows. - Automatyczne wykrywanie backendu wymaga OpenSSL 3.x dla ścieżki dostawcy; LibreSSL nigdy nie rozwiązuje się do dostawcy. Gdy nie powiedzie się ani sonda dostawcy, ani silnika, konstrukcja zawodzi z
HsmOperationException, zamiast odkładać awarię na czas podpisu. - Podproces przekraczający
$timeoutSecondsjest przerywany i raportowany jako timeout; podproces, który kończy się czysto z pustym wyjściem, jest raportowany jako awaria pustego podpisu. Żaden z tych warunków nie może wytworzyć częściowo podpisanego dokumentu. - Podpis post-kwantowy, którego długość bajtowa nie zgadza się z wybranym zestawem parametrów, jest odrzucany, zanim może dotrzeć do kodowania CMS.
HsmSignerProviderAdapterz wycofanym id dostawcyopenssl-enginenie rozgłasza żadnych algorytmów, więc nieaktualna konfiguracja zawodzi przy wyborze dostawcy, a nie w czasie podpisu.
Zachowanie w trybie FIPS
Dział zatytułowany „Zachowanie w trybie FIPS”Oba sygnatariusze akceptują opcjonalny FipsSignatureEnforcer. Gdy jest podłączony, tryb FIPS jest aktywny dla tego sygnatariusza: sign() odrzuca niedozwolony algorytm podpisu lub klucz poniżej progu przed jakimkolwiek podpisywaniem na tokenie lub w podprocesie. Progi podążają za tabelą generowania podpisu — moduły RSA poniżej 2048 bitów oraz rzędy ECDSA poniżej 224 bitów są niedozwolone (NIST SP 800-131A Rev.2 §3 Table 2). Bez enforcera zachowanie pozostaje niezmienione. Bramka obejmuje wyłącznie klasyczną ścieżkę sign(); signPqs() jest regulowane własną flagą podglądu. Są to oświadczenia o możliwościach dotyczące kodu NextPDF: walidacja FIPS 140-3 przywiązuje się do modułu kryptograficznego poprzez CMVP, którym w tym wdrożeniu jest HSM lub dostawca operatora — NextPDF nie jest zwalidowanym modułem, nie posiada żadnej certyfikacji i żadnej nie udziela.
Zgodność
Dział zatytułowany „Zgodność”| Oświadczenie | Standard | Klauzula |
|---|---|---|
| Logowanie uwierzytelnia użytkownika wobec tokenu przed operacjami klucza prywatnego; błędny PIN odmawia dostępu. | PKCS#11 v3.1 | §5.6.8 |
| Klucze always-authenticate potrzebują świeżego logowania na użycie; powtarzające się nieudane ponowne uwierzytelnienie może zablokować PIN. | PKCS#11 v3.1 | CKA_ALWAYS_AUTHENTICATE re-authentication |
| Podpis ECDSA tokenu to surowa konkatenacja r‖s; sygnatariusz konwertuje ją do DER dla interoperacyjności PDF. | PKCS#11 v3.1 | §6.3.1 |
| Parametry PSS wiążą hash, MGF i długość soli; sygnatariusze ustawiają sól równą długości skrótu. | PKCS#11 v3.1 | §6.1.9 |
| Bramka FIPS odmawia generowania podpisu z RSA poniżej 2048 bitów lub rzędem ECDSA poniżej 224 bitów. | NIST SP 800-131A Rev.2 | §3 Table 2 |
| Ciąg kontekstu post-kwantowego jest ograniczony do 255 bajtów. | FIPS 204 | HashML-DSA context handling |
| Walidacja FIPS 140-3 przywiązuje się do modułów kryptograficznych poprzez CMVP. | FIPS 140-3 | CMVP program scope |
Wszystkie klauzule są parafrazowane; nie odtworzono żadnego tekstu normatywnego. NextPDF nie składa żadnego oświadczenia o certyfikacji. Sygnatariusze dostosowują swoje zachowanie do cytowanych klauzul jako możliwość. To, czy wytworzony podpis się weryfikuje, jest decyzją weryfikatora wobec jego kotwic zaufania; bezpieczeństwo klucza zależy od tokenu, HSM i operatora — nie od samego NextPDF.
Uwagi deweloperskie
Dział zatytułowany „Uwagi deweloperskie”-
Mechanizm dostarczania PIN-u podąża za konwencją
pin-sourcew URI PKCS#11 (RFC 7512); ten RFC jest poza cytowanym korpusem, więc powyższe zachowanie jest ugruntowane w źródle produktu, a nie w cytacie ze specyfikacji. -
Potwierdź, że środowisko uruchomieniowe wczytuje
ext-pkcs11przed skonstruowaniemPkcs11Signer; konstrukcja zawodzi szybko, gdy rozszerzenia brakuje. Sygnatariusz CLI potrzebuje włączonegoproc_openoraz binariumopensslz zainstalowanym dostawcą lub silnikiem PKCS#11. -
PIN, etykieta certyfikatu i etykieta klucza mają
#[SensitiveParameter], więc są wykluczone ze śladów stosu. Dostarczaj PIN z menedżera sekretów; nigdy nie zapisuj go w źródle, konfiguracji zatwierdzonej do systemu kontroli wersji ani w logach. -
Konstrukcja jest kosztownym krokiem na obu sygnatariuszach: ścieżka PKCS#11 loguje się i czyta certyfikat, a ścieżka CLI sonduje binarium i backend. Skonstruuj raz i używaj ponownie tej instancji; bufor modułu na bibliotekę czyni powtarzaną konstrukcję wobec tej samej biblioteki bezpieczną.
-
Opakuj sygnatariusza w
HsmSignerProviderAdapter, gdy wywołujący działa przezSignerProviderInterface. Przekaż kanoniczne id dostawcy dla opakowanej klasy —pkcs11-{module-id}lubopenssl-cli— aby sprawdzenia możliwości używały właściwego zbioru dozwolonego backendu. -
Przed włączeniem podglądu post-kwantowego zweryfikuj identyfikatory mechanizmu firmware’u tokenu wobec prowizorycznych wartości, które rejestruje NextPDF; niezgodność zawodzi w czasie podpisu. Nie włączaj podglądu dla produkcyjnego wyjścia PAdES.
-
getResolvedBackend()igetOpensslVersion()istnieją do zapisywania dowodów; utrwalaj je wraz z dowodem podpisu, gdy twój program zgodności wymaga odtwarzalności.
Zobacz także
Dział zatytułowany „Zobacz także”- Podpisywanie modułem sprzętowego bezpieczeństwa (PKCS#11) — strona funkcji z krokami konfiguracji, ustawień i weryfikacji.
- Bezpieczeństwo — dogłębna dokumentacja — połączona powierzchnia bezpieczeństwa Enterprise.
- Podpis — dogłębna dokumentacja — długoterminowy producent PAdES B-LT / B-LTA.
- FIPS 140 — dogłębna dokumentacja — polityka kryptograficzna, bateria autotestów oraz bramka
FipsSignatureEnforcer. - Podgląd PQC — dogłębna dokumentacja — powierzchnia podglądu post-kwantowego i jej granice.
- Bezpieczeństwo / Podpisywanie (Core) — sygnatariusz CMS Core i kontrakty podpisywania.
Granica publikacji
Dział zatytułowany „Granica publikacji”Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie oraz obsługiwaną powierzchnię publicznego API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków oraz prefiksy zgłoszeń są poza zakresem.