Enterprise Edition
HSM-Signierung — Ausführliche Referenz
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Diese Seite ist die ausführliche Referenz für die HSM-Signierschnittstelle von NextPDF Enterprise. Sie behandelt drei öffentliche Typen. NextPDF\Enterprise\Security\Signature\Hsm\Pkcs11Signer signiert über ein PKCS#11-Token mittels der ext-pkcs11-Erweiterung. NextPDF\Enterprise\Security\Signature\Hsm\OpenSslCliSigner signiert über die openssl-Binärdatei in einem Subprozess, für Provider- oder Engine-gestützte Schlüssel, die PHP ext-openssl nicht laden kann. NextPDF\Enterprise\Security\Signature\Hsm\Provider\HsmSignerProviderAdapter stellt jede der beiden Konkretisierungen als einheitliches SignerProviderInterface bereit. In jedem Pfad bleibt der private Schlüssel innerhalb der Token-Grenze; NextPDF übergibt die zu signierenden Bytes und erhält die Signatur zurück. Der Post-Quantum-Pfad (signPqs) ist eine Vorschau: er ist standardmäßig deaktiviert, trägt keinen Konformitätsanspruch und hat in aktuellen PDF-Validatoren keinen unterstützten Verifikationspfad. NextPDF besitzt keine Zertifizierung und gewährt keine; Unterstützung ist nicht gleich Konformität, und Konformität ist nicht gleich Zertifizierung.
Verfügbarkeit & Lizenzierung
Abschnitt betitelt „Verfügbarkeit & Lizenzierung“Diese Fähigkeit wird mit NextPDF Enterprise (nextpdf/enterprise) ausgeliefert und aktiviert sich mit einem Lizenz-Envelope der Enterprise-Stufe. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und eine Lizenz erwerben.
Öffentliche API-Oberfläche
Abschnitt betitelt „Öffentliche API-Oberfläche“Alle drei Typen liegen in NextPDF\Enterprise\Security\Signature\Hsm; der Adapter befindet sich in dessen Provider-Unter-Namespace. Beide Signierer implementieren den Core-Vertrag NextPDF\Contracts\HsmSignerInterface.
| Symbol | Parameter | Standardverhalten | Rückgabe | Wirft oder scheitert mit | Hinweise |
|---|---|---|---|---|---|
Pkcs11Signer::__construct() | string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null | Öffnet die Hersteller-Library, meldet sich am Slot an und lädt das Zertifikat sowie die Schlüsselalgorithmus-Metadaten vom Token | — | HsmOperationException, wenn ext-pkcs11 fehlt oder der Token-Zugriff scheitert | Ein Modul-Handle wird pro Library-Pfad pro Prozess zwischengespeichert; PIN und Labels sind #[SensitiveParameter] |
Pkcs11Signer::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Signiert auf dem Token; die rohe ECDSA-Ausgabe wird in DER ECDSA-Sig-Value konvertiert | string rohe Signaturbytes | HsmOperationException (Schlüssel nicht gefunden, Token-Ausfall); InvalidArgumentException (nicht zugeordneter Algorithmus); FIPS-Gate-Ausnahmen vor dem Signieren, wenn ein Enforcer verdrahtet ist | Geschlossene Algorithmusmenge; siehe Verhaltensvertrag |
Pkcs11Signer::signPqs() | string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true | Verweigert, sofern $enablePostQuantum nicht gesetzt wurde; ruft den provisorischen PKCS#11-PQ-Mechanismus auf | string rohe Signaturbytes | HsmOperationException (deaktiviert, Token-Ausfall, Signaturlängen-Diskrepanz); InvalidArgumentException (Kontext über 255 Bytes) | Vorschau; kein Konformitätsanspruch; Mechanismus-Identifikatoren sind provisorisch |
Pkcs11Signer::isPostQuantumEnabled() | Keine | Meldet das Opt-in-Flag des Konstruktors | bool | Keine | — |
Pkcs11Signer::getCertificateDer() | Keine | Gibt das vom Token gelesene Signierzertifikat zurück | string (DER) | Keine | Wird einmal bei der Konstruktion geladen |
Pkcs11Signer::getCertificateChainDer() | Keine | Gibt die vom Konstruktor gelieferten Zwischenzertifikate zurück | array<string> (DER) | Keine | Schließt das Signierzertifikat aus |
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 | Verifiziert proc_open, prüft die Binärdatei und Version, ermittelt das Backend und lädt die Zertifikate | — | HsmOperationException (proc_open deaktiviert, fehlende Modul-/Konfig-/Zertifikatsdatei, Binär-Ausfall, kein Backend); InvalidArgumentException (pin-value innerhalb $keyUri) | OpenSslCliBackend::Auto bevorzugt den OpenSSL-3.x-Provider, dann die Engine |
OpenSslCliSigner::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Führt openssl dgst in einem Subprozess aus; die PIN wandert standardmäßig durch eine ephemere 0600-pin-source-Datei | string rohe Signaturbytes | HsmOperationException (Timeout, PIN abgelehnt, Schlüssel nicht gefunden, Modul-Ladefehler, leere Ausgabe, pin-file-Fehler); InvalidArgumentException (nicht zugeordneter Algorithmus); FIPS-Gate-Ausnahmen vor dem Signieren | Der Subprozess wird nach $timeoutSeconds beendet; stderr wird redigiert, bevor es in Meldungen gelangt |
OpenSslCliSigner-Accessor-Oberfläche | Keine | Schreibgeschützte Konstruktionsergebnisse | string / array<string> / OpenSslCliBackend | Keine | getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion |
HsmSignerProviderAdapter::__construct() | HsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15 | Umschließt eine HSM-Konkretisierung als SignerProviderInterface | — | Keine | Provider-ID-Konventionen: pkcs11-{module-id}, openssl-cli |
HsmSignerProviderAdapter::providerId() | Keine | Gibt die vom Konstruktor gelieferte ID zurück | non-empty-string | Keine | — |
HsmSignerProviderAdapter::supportsAlgorithm() | SignatureAlgorithm $algo | Ordnet das Enum einem Namen im OpenSSL-Stil zu und schneidet es dann mit der Backend-Zulassungsmenge | bool | Keine | Lehnt reine Digest-Algorithmen ab; openssl-engine-IDs bewerben nichts |
HsmSignerProviderAdapter::sign() | string $data, ?string $keyVersion = null | Reicht über den umschlossenen Signierer mit dem konfigurierten Algorithmus weiter | non-empty-string | KeyManagementException (nicht-null $keyVersion); SignatureFailedException (nicht zuordenbarer Algorithmus, Treiber-Ausfall, leere Signatur) | Fail-closed-SPI-Vertrag; jeder Treiberfehler tritt typisiert zutage |
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): stringVerhaltensvertrag
Abschnitt betitelt „Verhaltensvertrag“- Schlüsselverwahrung. Der private Schlüssel verlässt niemals die Token-Grenze.
Pkcs11Signerdelegiert die Operation an das Token;OpenSslCliSignerübergibt eine Schlüssel-Referenz — eine PKCS#11-URI — an denopenssl-Subprozess. Keiner der Signierer kann den Schlüssel exportieren. - Sitzung und Anmeldung.
Pkcs11Signerspeichert ein PKCS#11-Modul-Handle pro Library-Pfad pro Prozess zwischen, da die Token-Schnittstelle genau einmal pro Prozess initialisiert werden muss. Jede Operation öffnet eine Sitzung und meldet sich mit der PIN an; die Anmeldung authentifiziert den Benutzer vor jeder Nutzung des privaten Schlüssels (PKCS#11 v3.1 §5.6.8). Wenn der Slot eine bestehende Anmeldung meldet, meldet sich der Signierer ab und erneut an, sodass Tokens, die pro Operation eine frische PIN verlangen, eine solche erhalten. - Algorithmusmenge (geschlossen). Beide Signierer akzeptieren genau:
sha256WithRSAEncryption,sha384WithRSAEncryption,sha512WithRSAEncryption;RSASSA-PSS,RSASSA-PSS-SHA256,RSASSA-PSS-SHA384,RSASSA-PSS-SHA512;ecdsa-with-SHA256,ecdsa-with-SHA384,ecdsa-with-SHA512.Pkcs11Signerakzeptiert zusätzlichecdsa-raw. Jeder andere Identifikator löstInvalidArgumentExceptionaus — es wird niemals ein Ersatzalgorithmus signiert. - PSS-Salt-Bindung. Für jede PSS-Variante entspricht die Salt-Länge der Digest-Länge — 32, 48 oder 64 Bytes — und die Hash- und MGF-Parameter passen zum gewählten Digest. Dies folgt der PSS-Mechanismus-Parameterstruktur, in der die Salt-Länge typischerweise die Länge des Nachrichten-Hashs ist (PKCS#11 v3.1 §6.1.9). Beide Signierer wenden dieselbe Paarung an, sodass eine auf einem Backend gültige Konfiguration auch auf dem anderen gültig ist.
- ECDSA-Konvertierung. Ein Token gibt eine ECDSA-Signatur als rohe, mit Nullen aufgefüllte Verkettung von r und s zurück (PKCS#11 v3.1 §6.3.1).
Pkcs11Signer::sign()konvertiert diese Ausgabe in die DER-kodierteECDSA-Sig-Value-Form, die PDF-Validatoren und OpenSSL erwarten. Der Aufrufer verarbeitet niemals die rohe Form. - PIN-Übergabe (CLI-Pfad). Im sicheren Standard wird die PIN in eine ephemere Datei geschrieben, die exklusiv mit Nur-Eigentümer-Berechtigungen erstellt wird, über das PKCS#11-URI-Attribut
pin-sourcereferenziert und nach Beendigung des Subprozesses entfernt (unlink). Die PIN wird in diesem Modus nicht in die Befehlszeile gestellt und nicht in die Subprozess-Umgebung exportiert. Mit$legacyPinDelivery = truewird die PIN alspin-valuein die URI eingebettet, was in der Prozess-Befehlszeile beobachtbar ist; dieser Modus ist ausschließlich Opt-in. - Subprozess-Disziplin.
OpenSslCliSignerstartet die Binärdatei mit einem Argument-Array — keine Shell-Interpolation —, erzwingt$timeoutSeconds, beendet den Subprozess bei Ablauf und klassifiziert stderr in typisierte Fehler. Geheimnisse werden aus stderr redigiert, bevor es in einer Ausnahmemeldung zitiert wird. - Adapter-Semantik. Ein HSM-Token hat kein verwaltetes Schlüsselversions-Konzept; der Schlüssel auf dem Token ist die Version.
HsmSignerProviderAdapter::sign()weist daher jede nicht-null$keyVersionmitKeyManagementExceptionzurück, anstatt sie zu ignorieren.supportsAlgorithm()schneidet die Enum-Zuordnung mit der akzeptierten Menge des umschlossenen Backends, sodass der Adapter niemals einen Mechanismus bewirbt, den das Backend zur Signierzeit ablehnen würde. Eine leere Signatur vom Treiber löstSignatureFailedExceptionaus. - Post-Quantum-Vorschau.
signPqs()ist hinter das Konstruktor-Flag$enablePostQuantumgestellt und verweigert andernfalls die Ausführung. Die Kontextzeichenkette ist auf 255 Bytes begrenzt, passend zur ML-DSA-Kontextgrenze (FIPS 204). Die zurückgegebene Signatur muss der exakten Byte-Länge des gewähltenPkcs11PqsAlgorithm-Parametersatzes entsprechen, sonst schlägt der Aufruf fehl. Die Mechanismus-Identifikatoren folgen einer provisorischen PKCS#11-PQ-Erweiterung und sind nicht endgültig. PAdES-Profile erkennen keine Post-Quantum-Suites, die meisten PDF-Validatoren lehnen solche Signaturen ab, und NextPDF stellt keinen Verifikationspfad für sie bereit. Es wird keine Konformität beansprucht.
Grenzfälle & Fehlermodi
Abschnitt betitelt „Grenzfälle & Fehlermodi“- Die Konstruktion von
Pkcs11Signerohneext-pkcs11löst sofortHsmOperationExceptionaus; die Erweiterung ist nicht in den Standard-PHP-Distributionen enthalten. - Ein Zertifikats- oder Privatschlüssel-Label, das keinem Objekt auf dem Token entspricht, löst
HsmOperationExceptionaus und benennt die fehlende Objektklasse. Das Schlüssel-Label darf auf manchen Tokens legitim vom Zertifikats-Label abweichen. - Wiederholt fehlgeschlagene Anmeldungen können die PIN am Token sperren; das Token erzwingt diese Richtlinie, nicht NextPDF. Tokens, deren Schlüssel bei jeder Nutzung eine Authentifizierung erfordern, erhalten über den Abmelde-und-erneut-Versuch-Pfad eine frische Anmeldung (PKCS#11 v3.1, Always-authenticate-Semantik).
OpenSslCliSignerverweigert bei der Konstruktion fail-closed eine$keyUri, die bereitspin-valueenthält, da diese Übergabe den sicheren PIN-Pfad umgehen würde.- Unter Windows schlägt der sichere pin-file-Modus mit
HsmOperationExceptionfail-closed fehl: Dateiberechtigungsbits können dort ACL-Lesegewährungen nicht einschränken, sodass der Signierer sich weigert, eine Klartext-PIN in der ACL des Temp-Verzeichnisses zu hinterlassen. Die Legacy-PIN-Übergabe ist die dokumentierte Opt-in-Alternative für vertrauenswürdige Windows-Hosts. - Die automatische Backend-Erkennung erfordert OpenSSL 3.x für den Provider-Pfad; LibreSSL löst niemals zum Provider auf. Wenn weder eine Provider- noch eine Engine-Prüfung erfolgreich ist, schlägt die Konstruktion mit
HsmOperationExceptionfehl, anstatt den Fehler auf die Signierzeit zu verschieben. - Ein Subprozess, der
$timeoutSecondsüberschreitet, wird beendet und als Timeout gemeldet; ein Subprozess, der sauber mit leerer Ausgabe endet, wird als Fehler „leere Signatur“ gemeldet. Keine der beiden Bedingungen kann ein teilweise signiertes Dokument erzeugen. - Eine Post-Quantum-Signatur, deren Byte-Länge nicht zum gewählten Parametersatz passt, wird abgewiesen, bevor sie die CMS-Kodierung erreichen kann.
HsmSignerProviderAdaptermit der ausgemusterten Provider-IDopenssl-enginebewirbt keine Algorithmen, sodass eine veraltete Konfiguration bei der Provider-Auswahl statt zur Signierzeit fehlschlägt.
FIPS-Modus-Verhalten
Abschnitt betitelt „FIPS-Modus-Verhalten“Beide Signierer akzeptieren einen optionalen FipsSignatureEnforcer. Ist einer verdrahtet, ist der FIPS-Modus für diesen Signierer aktiv: sign() weist einen unzulässigen Signaturalgorithmus oder einen Schlüssel unterhalb der Untergrenze vor jeder Token- oder Subprozess-Signierung zurück. Die Untergrenzen folgen der Tabelle zur Signaturerzeugung — RSA-Moduli unter 2048 Bit und ECDSA-Ordnungen unter 224 Bit sind unzulässig (NIST SP 800-131A Rev.2 §3 Table 2). Ohne Enforcer bleibt das Verhalten unverändert. Das Gate deckt nur den klassischen sign()-Pfad ab; signPqs() unterliegt seinem eigenen Vorschau-Flag. Dies sind Fähigkeitsaussagen über NextPDF-Code: Die FIPS-140-3-Validierung heftet sich über die CMVP an ein kryptografisches Modul, das in dieser Bereitstellung das HSM oder der Provider des Betreibers ist — NextPDF ist kein validiertes Modul, besitzt keine Zertifizierung und gewährt keine.
Konformität
Abschnitt betitelt „Konformität“| Anspruch | Standard | Klausel |
|---|---|---|
| Die Anmeldung authentifiziert den Benutzer vor Operationen mit dem privaten Schlüssel am Token; eine falsche PIN verweigert den Zugriff. | PKCS#11 v3.1 | §5.6.8 |
| Always-authenticate-Schlüssel benötigen eine frische Anmeldung pro Nutzung; wiederholt fehlgeschlagene Re-Authentifizierung kann die PIN sperren. | PKCS#11 v3.1 | CKA_ALWAYS_AUTHENTICATE re-authentication |
| Eine Token-ECDSA-Signatur ist die rohe r‖s-Verkettung; der Signierer konvertiert sie für die PDF-Interoperabilität in DER. | PKCS#11 v3.1 | §6.3.1 |
| PSS-Parameter binden Hash, MGF und Salt-Länge; die Signierer setzen das Salt gleich der Digest-Länge. | PKCS#11 v3.1 | §6.1.9 |
| Das FIPS-Gate verweigert die Signaturerzeugung mit RSA unter 2048 Bit oder ECDSA-Ordnung unter 224 Bit. | NIST SP 800-131A Rev.2 | §3 Table 2 |
| Die Post-Quantum-Kontextzeichenkette ist auf 255 Bytes begrenzt. | FIPS 204 | HashML-DSA context handling |
| Die FIPS-140-3-Validierung heftet sich über die CMVP an kryptografische Module. | FIPS 140-3 | CMVP program scope |
Alle Klauseln sind paraphrasiert; kein normativer Text wird wiedergegeben. NextPDF erhebt keinen Zertifizierungsanspruch. Die Signierer richten ihr Verhalten als Fähigkeit an den zitierten Klauseln aus. Ob eine erzeugte Signatur verifiziert, ist die Entscheidung des Verifizierers gegen seine Vertrauensanker; die Schlüsselsicherheit hängt vom Token, vom HSM und vom Betreiber ab — nicht von NextPDF allein.
Entwicklungshinweise
Abschnitt betitelt „Entwicklungshinweise“-
Der PIN-Übergabemechanismus folgt der PKCS#11-URI-Konvention
pin-source(RFC 7512); dieser RFC liegt außerhalb des zitierten Korpus, sodass das obige Verhalten aus der Produktquelle abgeleitet ist, nicht aus einer Spezifikationszitierung. -
Stellen Sie sicher, dass die Laufzeit
ext-pkcs11lädt, bevor SiePkcs11Signerkonstruieren; die Konstruktion schlägt schnell fehl, wenn die Erweiterung fehlt. Der CLI-Signierer benötigt aktiviertesproc_openund eineopenssl-Binärdatei mit installiertem PKCS#11-Provider oder -Engine. -
Die PIN, das Zertifikats-Label und das Schlüssel-Label sind
#[SensitiveParameter], sodass sie aus Stacktraces ausgeschlossen werden. Liefern Sie die PIN aus einem Secret-Manager; schreiben Sie sie niemals in Quellcode, in unter Versionskontrolle eingecheckte Konfiguration oder in Logs. -
Die Konstruktion ist bei beiden Signierern der teure Schritt: Der PKCS#11-Pfad meldet sich an und liest das Zertifikat, und der CLI-Pfad prüft Binärdatei und Backend. Konstruieren Sie einmal und verwenden Sie die Instanz wieder; der Modul-Cache pro Library macht wiederholte Konstruktion gegen dieselbe Library sicher.
-
Umschließen Sie einen Signierer in
HsmSignerProviderAdapter, wenn der Aufrufer überSignerProviderInterfacearbeitet. Übergeben Sie die kanonische Provider-ID für die umschlossene Klasse —pkcs11-{module-id}oderopenssl-cli—, damit Fähigkeitsprüfungen die korrekte Backend-Zulassungsmenge verwenden. -
Verifizieren Sie vor dem Aktivieren der Post-Quantum-Vorschau die Mechanismus-Identifikatoren der Token-Firmware gegen die provisorischen Werte, die NextPDF registriert; eine Diskrepanz schlägt zur Signierzeit fehl. Aktivieren Sie die Vorschau nicht für produktive PAdES-Ausgabe.
-
getResolvedBackend()undgetOpensslVersion()existieren zur Beweisaufzeichnung; persistieren Sie sie zusammen mit Signierbeweisen, wenn Ihr Compliance-Programm Reproduzierbarkeit erfordert.
Siehe auch
Abschnitt betitelt „Siehe auch“- Hardware-Security-Module-Signierung (PKCS#11) — die Fähigkeitsseite mit Einrichtungs-, Konfigurations- und Verifikationsschritten.
- Sicherheit — Ausführliche Referenz — die kombinierte Enterprise-Sicherheitsoberfläche.
- Signatur — Ausführliche Referenz — der PAdES-B-LT-/B-LTA-Langzeit-Erzeuger.
- FIPS 140 — Ausführliche Referenz — die Krypto-Richtlinie, die Selbsttest-Batterie und das
FipsSignatureEnforcer-Gate. - PQC-Vorschau — Ausführliche Referenz — die Post-Quantum-Vorschauoberfläche und ihre Grenzen.
- Sicherheit / Signierung (Core) — der Core-CMS-Signierer und die Signierverträge.
Publikationsgrenze
Abschnitt betitelt „Publikationsgrenze“Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismus-Tabellen, Runbook-Dateinamen und Ticket-Präfixe liegen außerhalb des Geltungsbereichs.