Enterprise edizione
Security — Riferimento approfondito (HSM, PKCS#11, modalità FIPS)
In sintesi
Sezione intitolata “In sintesi”Questa pagina è il riferimento approfondito combinato per la superficie di sicurezza di NextPDF Enterprise. Copre la firma con token hardware tramite PKCS#11, la firma in sottoprocesso attraverso l’interfaccia a riga di comando (CLI) di OpenSSL, i preset di crypto-policy FIPS, la guardia FIPS in fase di esecuzione e la guardia di self-test all’accensione (power-on). Esistono due complementi mirati: HSM — Riferimento approfondito per il dettaglio del firmatario e FIPS 140 — Riferimento approfondito per il dettaglio del modulo FIPS. Il percorso di firma post-quantistico è un’anteprima priva di rivendicazioni di conformità. NextPDF non detiene alcuna certificazione e non ne concede alcuna; il supporto non equivale alla conformità e la conformità non equivale alla certificazione.
Disponibilità e licenze
Sezione intitolata “Disponibilità e licenze”Questa funzionalità è distribuita in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di tier Enterprise. Una distribuzione priva di tale entitlement non carica le classi della funzionalità. Confronta le edizioni e ottieni una licenza.
Superficie API pubblica
Sezione intitolata “Superficie API pubblica”composer require nextpdf/enterprise:^3I tipi di firma risiedono in NextPDF\Enterprise\Security\Signature\Hsm; i tipi FIPS risiedono in NextPDF\Enterprise\Security\Fips; la composition root risiede in NextPDF\Enterprise\Bootstrap. Entrambi i firmatari implementano il contratto di Core NextPDF\Contracts\HsmSignerInterface. La policy implementa i contratti di Core NextPDF\Contracts\CryptoPolicyInterface e NextPDF\Contracts\PreOperationalSelfTestInterface.
| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
Pkcs11Signer::__construct() | string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null | Apre la libreria del fornitore, effettua il login nello slot, carica il certificato e i metadati dell’algoritmo di chiave | — | HsmOperationException quando ext-pkcs11 è assente o l’accesso al token fallisce | PIN e label sono #[SensitiveParameter]; un handle di modulo viene messo in cache per percorso di libreria per processo |
Pkcs11Signer::isAvailable() | Nessuno | Indica se ext-pkcs11 è caricato | bool | Nessuno | Statico; verificare prima della costruzione |
Pkcs11Signer::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Firma sul token; l’output ECDSA raw viene convertito in DER ECDSA-Sig-Value | string byte di firma raw | HsmOperationException (chiave non trovata, errore del token); InvalidArgumentException (algoritmo non mappato); FipsViolationException / FipsModuleErrorStateException prima della firma quando è collegato un enforcer | Insieme di algoritmi chiuso; vedere Contratto di comportamento |
Pkcs11Signer::signPqs() | string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true | Rifiutato a meno che $enablePostQuantum non sia stato impostato; invoca il meccanismo post-quantistico PKCS#11 provvisorio | string byte di firma raw | HsmOperationException (disabilitato, errore del token, lunghezza della firma non corrispondente); InvalidArgumentException (contesto oltre 255 byte) | Anteprima; nessuna rivendicazione di conformità |
Superficie di accessor di Pkcs11Signer | Nessuno | Risultati di costruzione in sola lettura | bool / string / array<string> | Nessuno | 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 | Verifica proc_open, sonda il binario, risolve il backend, carica i certificati | — | HsmOperationException (proc_open disabilitato, file di modulo/config/certificato mancante, nessun backend); InvalidArgumentException (pin-value all’interno di $keyUri) | Auto preferisce il provider OpenSSL 3.x, poi l’engine |
OpenSslCliSigner::sign() | string $data, string $algorithm = 'sha256WithRSAEncryption' | Firma in un sottoprocesso openssl; per impostazione predefinita il PIN transita attraverso un file pin-source effimero 0600 | string byte di firma raw | HsmOperationException (timeout, PIN rifiutato, chiave non trovata, output vuoto); InvalidArgumentException (algoritmo non mappato); eccezioni del gate FIPS prima della firma | Il sottoprocesso viene terminato dopo $timeoutSeconds; stderr è redatto |
Superficie di accessor di OpenSslCliSigner | Nessuno | Risultati di costruzione in sola lettura | string / array<string> / OpenSslCliBackend | Nessuno | getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion |
OpenSslCliBackend | — | Enum: Provider, Engine, Auto | — | Nessuno | Selezione del backend per il firmatario CLI |
Pkcs11PqsAlgorithm | — | Enum di set di parametri ML-DSA e SLH-DSA | — | Nessuno | Helper: isMlDsa, isSlhDsa, mechanismId, parameterSetId, signatureLength, nistCategory |
PqsCapabilityStatus::current() | Nessuno | Costruisce la postura post-quantistica onesta per il processo | PqsCapabilityStatus | Nessuno | Ogni booleano di rivendicazione di conformità è impostato in modo fisso a false; nessun flag può attivarne uno |
HsmSignerProviderAdapter | HsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15 | Espone una concreta HSM come SignerProviderInterface unificata | Secondo lo SPI | KeyManagementException (versione di chiave non nulla); SignatureFailedException (errore del driver, firma vuota) | Id dei provider: pkcs11-{module-id}, openssl-cli |
HsmOperationException | — | Errore tipizzato per ogni percorso di firma HSM | — | — | Estende NextPdfException di Core |
FipsCryptoPolicy::strict() / ::standard() | ?FipsSelfTest $selfTest = null | Preset di factory; strict è il profilo FIPS 140-3, standard aggiunge AES-128-CBC | FipsCryptoPolicy | Nessuno | Allow-list immutabili; vedere Comportamento in modalità FIPS |
Superficie di predicati di FipsCryptoPolicy | input string / int | Verifiche di appartenenza all’allow-list | bool / string | Nessuno | isHashAlgorithmAllowed, isSignatureAlgorithmAllowed, isEncryptionAlgorithmAllowed, isKeyStrengthAllowed, getPreferredHashAlgorithm, getName |
FipsCryptoPolicy::assertPreOperational() | Nessuno | Esegue (o riproduce) il self-test all’accensione | void | FipsModuleErrorStateException | Guidato dalla giuntura (seam) di enforcement di Core alla prima operazione crittografica |
FipsModeGuard::__construct() | CryptoPolicyInterface $policy, ?FipsBootGuard $bootGuard = null, ?FipsAuditLogger $auditLogger = null | Avvolge una policy con confini in stile assert | — | Nessuno | Senza una boot guard il gate di self-test è assente (solo policy) |
Superficie di assert di FipsModeGuard | input string / int | Prima il catalogo di deny, poi l’allow-list; record di audit prima di qualsiasi eccezione | void | FipsViolationException; FipsModuleErrorStateException (boot guard collegata) | assertHashAllowed, assertSignatureAlgorithmAllowed, assertEncryptionAllowed, assertKeyStrengthAllowed, più getPolicy |
FipsBootGuard::report() / ::rerun() | Nessuno | Esegue la batteria di self-test (in cache / forzata) | FipsSelfTestReport | Nessuno | Un report ERROR blocca (latch) il processo; una riesecuzione superata non rimuove mai il latch |
FipsBootGuard::assertOperational() | Nessuno | Asserisce che il modulo sia OPERATIONAL | void | FipsModuleErrorStateException | Persistente (sticky): un ERROR bloccato a livello di processo rifiuta anche un’istanza pulita |
FipsBootGuard::status() | Nessuno | Riferisce lo stato in cache | FipsSelfTestStatus | Nessuno | PRE_OPERATIONAL, OPERATIONAL o ERROR |
FipsSelfTest::run() | Nessuno | Esegue l’intera batteria di test a risposta nota (known-answer-test); non va mai in corto circuito | FipsSelfTestReport | Nessuno | Il costruttore accetta provider di hash e di byte casuali iniettabili per test deterministici |
FipsSelfTestReport / FipsSelfTestResult / FipsSelfTestStatus | — | Value object di report ed enum di stato | — | FipsSelfTestReport::assertOperational() solleva FipsModuleErrorStateException | results elenca sempre ogni esito come evidenza di audit |
FipsSignatureEnforcer::assertSignatureGenerationAllowed() | string $algorithm, string $certificatePem | Risolve l’OID di firma e la robustezza della chiave, poi delega alla guardia | void | FipsViolationException (non consentito o non classificabile, fail-closed) | Il punto di strozzatura (chokepoint) che entrambi i firmatari chiamano all’inizio di sign() in modalità FIPS |
FipsAuditLogger | CryptoPolicyInterface $policy, LoggerInterface $logger | Emette record ALLOW (INFO) / DENY (WARNING) per ogni decisione | bool per chiamata di log | Nessuno | logHashOperation, logSignatureOperation, logEncryptionOperation, logKeyStrengthCheck |
FipsTransitioningAlgorithms | input string / int | Catalogo di deny statico NIST SP 800-131A | bool / array | Nessuno | Il livello di deny esplicito sotto ogni confine di guardia |
FipsBootstrap::boot() / ::lazy() | ?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null | Compone boot guard, policy e mode guard; boot() esegue subito il self-test, lazy() lo rinvia al primo confine | FipsModeGuard | boot(): FipsModuleErrorStateException in caso di test fallito | Per impostazione predefinita usa la policy strict |
FipsBootstrap::signatureEnforcer() | ?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null | Avvia il modulo e restituisce il gate al momento della generazione per i firmatari | FipsSignatureEnforcer | FipsModuleErrorStateException | Passare il risultato al parametro $fipsEnforcer di un firmatario |
FipsBootstrap::selfTestReport() | ?FipsSelfTest $selfTest = null | Esegue la batteria on-demand e la riepiloga | array{status, operational, failed} | Nessuno | Pensato per endpoint di health e per il sottocomando CLI |
FipsViolationException / FipsModuleErrorStateException | — | Errori FIPS tipizzati | — | — | Espongono rispettivamente policyName / violatingItem / reason e 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(): boolpublic function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): stringpublic function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): stringpublic 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 static function strict(?FipsSelfTest $selfTest = null): selfpublic static function standard(?FipsSelfTest $selfTest = null): selfpublic function assertPreOperational(): voidpublic function __construct(private CryptoPolicyInterface $policy, private ?FipsBootGuard $bootGuard = null, private ?FipsAuditLogger $auditLogger = null)public function assertHashAllowed(string $algorithm): voidpublic function assertSignatureAlgorithmAllowed(string $oid): voidpublic function assertEncryptionAllowed(string $algorithm): voidpublic function assertKeyStrengthAllowed(string $keyType, int $bitLength): voidpublic function getPolicy(): CryptoPolicyInterfacepublic static function boot(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuardpublic static function lazy(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuardpublic static function signatureEnforcer(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null): FipsSignatureEnforcerpublic static function selfTestReport(?FipsSelfTest $selfTest = null): arrayContratto di comportamento
Sezione intitolata “Contratto di comportamento”- Risoluzione dei contratti. Entrambi i firmatari implementano
HsmSignerInterfacedi Core; la policy implementaCryptoPolicyInterfacedi Core. Il codice chiamante dipende dai contratti, quindi un upgrade di edizione cambia la composizione, non i punti di chiamata. - Custodia della chiave. La chiave privata non lascia mai il confine del token.
Pkcs11Signerdelega l’operazione al token;OpenSslCliSignerpassa al sottoprocesso un riferimento di chiave tramite URI PKCS#11. NextPDF non archivia, genera né garantisce la sicurezza della chiave di firma. La protezione della chiave è responsabilità di custodia dell’operatore (NIST SP 800-57 Part 1 Rev.5 §5.5.2). - Sessione e login. L’operazione di firma del token, la sessione e il login dell’utente seguono PKCS#11 v3.1 §5. La label del certificato e la label della chiave privata possono differire; il costruttore accetta una label di chiave separata per tali token.
- Insieme di algoritmi chiuso. I firmatari accettano esattamente: RSA PKCS#1 v1.5 con SHA-256/384/512, RSASSA-PSS con SHA-256/384/512 ed ECDSA con SHA-256/384/512 (
Pkcs11Signeraccetta ancheecdsa-raw). Qualsiasi altro identificatore sollevaInvalidArgumentException; nessun algoritmo sostitutivo viene mai firmato. - Vincolo del salt PSS. Per ogni variante PSS la lunghezza del salt è pari alla lunghezza del digest — 32, 48 o 64 byte — e i parametri di hash e di generazione della maschera corrispondono al digest scelto (PKCS#11 v3.1 §5).
- Conversione ECDSA. I meccanismi ECDSA del token restituiscono una firma raw;
sign()la converte nella formaECDSA-Sig-Valuecodificata in DER per l’interoperabilità con PDF e OpenSSL. La generazione della firma segue FIPS 186-5 §6.3.2. - Contenuto dei preset. Il preset strict consente SHA-256/384/512; gli OID di firma RSA ed ECDSA con tali hash; RSASSA-PSS; AES-256-CBC e AES-256-GCM; minimo RSA 2048 ed EC 256. Il preset standard consente inoltre AES-128-CBC per l’interoperabilità legacy. Qualsiasi uso di AES-GCM richiede un vettore di inizializzazione univoco per chiave (NIST SP 800-38D §5).
- Enforcement a due livelli. Ogni confine di guardia consulta prima il catalogo di deny esplicito NIST SP 800-131A, poi l’allow-list della policy. Il livello di deny produce il segnale «non consentito» chiaro per l’audit; l’allow-list rimane autoritativa.
- Self-test all’accensione. La batteria copre SHA-256/384/512, HMAC-SHA-256, AES-256-CBC, AES-256-GCM, un test di coerenza a coppie (pairwise-consistency) ECDSA P-256 e un controllo di integrità dei bit casuali. La prima operazione crittografica sotto la policy sul percorso di Core la esegue una volta per processo, fail-closed. Un fallimento pone il modulo nello stato ERROR; i servizi crittografici sono rifiutati fino al reset. Questo segue ISO/IEC 19790:2025 §7.10, §7.10.2, §7.10.3 e §7.10.3.p3.
- Stato ERROR persistente. Un ERROR osservato si blocca (latch) per l’intero processo. Costruire una nuova policy o boot guard non lo può ripulire; una riesecuzione superata non lo azzera. Solo un riavvio del processo — un vero ciclo di alimentazione — ripristina lo stato.
- Solo gate di generazione.
FipsSignatureEnforcergoverna la produzione di nuove firme. La convalida di firme preesistenti è un uso legacy e non passa mai attraverso l’enforcer. - Traccia di audit. Quando una guardia è composta con un audit logger, ogni confine emette un record ALLOW o DENY prima di consentire o rifiutare l’operazione. Il logger consulta la stessa policy che la guardia applica, quindi la decisione registrata non può divergere.
Casi limite e modalità di errore
Sezione intitolata “Casi limite e modalità di errore”- Costruire
Pkcs11Signersenzaext-pkcs11solleva immediatamenteHsmOperationException; l’estensione non è inclusa nelle distribuzioni PHP standard. - Una label di certificato o di chiave privata che non corrisponde ad alcun oggetto del token solleva
HsmOperationExceptionindicando la classe di oggetto mancante. OpenSslCliSignerrifiuta in costruzione, fail-closed, un$keyUricontenentepin-value; il PIN transita invece attraverso il percorso pin-source sicuro.- In modalità FIPS, un identificatore di algoritmo che non può essere mappato a un OID di firma noto viene negato fail-closed; lo stesso vale per un certificato la cui robustezza di chiave pubblica non può essere determinata.
- Un tipo di chiave sconosciuto viene negato per impostazione predefinita; la policy non ricade mai su un algoritmo più debole.
- Un test a risposta nota fallito solleva
FipsModuleErrorStateExceptionche trasporta i risultati falliti; ogni confine successivo nel processo ripete il fallimento fino al riavvio. - Una guardia costruita senza una boot guard applica le allow-list ma non fornisce alcun gate di self-test; la composizione FIPS di produzione ne fornisce uno tramite il bootstrap.
signPqs()rifiuta di essere eseguito a meno che non sia stato impostato l’opt-in nel costruttore. Una stringa di contesto oltre 255 byte sollevaInvalidArgumentException(FIPS 204 §5.4). Una firma restituita la cui lunghezza in byte non corrisponde al set di parametri selezionato viene rifiutata prima di raggiungere la codifica.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”Consentito da FIPS in modalità strict: SHA-256/384/512; RSA PKCS#1 v1.5 e RSA-PSS con tali hash; ECDSA con tali hash; AES-256-CBC e AES-256-GCM; RSA almeno 2048 bit, EC almeno 256 bit. Rifiutato da FIPS in modalità strict: hash più deboli o legacy, OID di firma non approvati, AES-128 (consentito solo nel preset standard) e qualsiasi chiave al di sotto della robustezza minima. La lunghezza minima della chiave RSA e lo stato di transizione seguono NIST SP 800-131A Rev.2 §3. L’accoppiamento di curva e hash ECDSA segue FIPS 186-5 §6.1.1. Il percorso è fail-closed e non sostituisce mai un algoritmo più debole.
NextPDF Enterprise non è un modulo crittografico convalidato FIPS e non avanza alcuna rivendicazione di certificazione FIPS. NextPDF Enterprise opera in modalità FIPS-compatibile solo quando è configurato con un provider crittografico convalidato FIPS — per esempio un provider OpenSSL convalidato FIPS — o con un HSM convalidato FIPS. La policy in modalità FIPS assiste la conformità; non è una certificazione. In questo repository non esiste alcun artefatto di certificazione FIPS.
Conformità
Sezione intitolata “Conformità”| Rivendicazione | Standard | Clausola |
|---|---|---|
| Semantica dell’operazione di firma del token, della sessione e del login dell’utente | PKCS#11 v3.1 | §5 (sign) |
| La lunghezza del salt PSS è pari alla lunghezza del digest | PKCS#11 v3.1 | §5 (PSS sLen) |
| Generazione della firma ECDSA; accoppiamento di curva e hash | FIPS 186-5 | §6.3.2; §6.1.1 |
| Lunghezza minima della chiave RSA e stato di transizione della generazione delle firme | NIST SP 800-131A Rev.2 | §3 |
| Categoria di self-test, documentazione, trigger condizionale, insieme disgiunto | ISO/IEC 19790:2025 | §7.10, §7.10.2, §7.10.3, §7.10.3.p3 |
| Univocità del vettore di inizializzazione AES-GCM | NIST SP 800-38D | §5 |
| Responsabilità di protezione e custodia delle chiavi | NIST SP 800-57 Part 1 Rev.5 | §5.5.2 |
| Stringa di contesto per la firma post-quantistica limitata a 255 byte | FIPS 204 | §5.4 |
Tutte le clausole sono parafrasate; nessun testo normativo viene riprodotto. Si tratta di rivendicazioni di capacità sul codice di NextPDF, non di certificazioni. Se una firma prodotta risulti valida è una decisione del verificatore rispetto alla propria configurazione di fiducia. La policy in modalità FIPS è una funzionalità di assistenza alla conformità, non un parere legale; consultare i propri consulenti legali e di conformità. Questo modulo riguarda funzionalità crittografiche; trattarlo come sensibile dal punto di vista della sicurezza nella propria revisione.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Comporre la modalità FIPS tramite il bootstrap:
boot()per un gate all’avvio,lazy()per rinviare la batteria al primo confine e la factory dell’enforcer per il parametro$fipsEnforcerdei firmatari. Le distribuzioni non-FIPS passanonulle il comportamento è invariato. - Il sottocomando
fips:self-testdibin/nextpdf-enterpriseesegue la batteria on-demand ed esce con codice diverso da zero nello stato ERROR; collegarlo a job di manutenzione o a endpoint di health riservati agli amministratori (self-test on-demand ISO/IEC 19790:2025). FipsBootGuard::resetProcessErrorLatchForTesting()è@internale solo per i test; il codice di produzione non lo chiama mai, perché vanificherebbe lo stato ERROR persistente.- Costruire i firmatari una volta e riutilizzarli; la costruzione effettua il login e legge il certificato, e la cache di modulo per libreria rende sicura la costruzione ripetuta sulla stessa libreria.
- Fornire il PIN da un secret manager. È un
#[SensitiveParameter], mai registrato nei log né serializzato; non inserirlo nella configurazione tramite commit. - L’operatore possiede il provisioning del token, la gestione del PIN, la configurazione dello slot, la protezione di rete di un HSM connesso in rete e la configurazione di fiducia. Questa pagina non espone i dettagli interni della policy di PIN del token né il materiale di credenziali del fornitore.
- Non abilitare l’anteprima post-quantistica per le firme AdES di produzione. Il catalogo delle suite crittografiche AdES non riconosce ancora le suite post-quantistiche, la maggior parte dei visualizzatori PDF rifiuta tali firme e la convalida hardware round-trip non è completa. Il dettaglio dei meccanismi interni resta nella documentazione interna del repository sorgente ed è fuori ambito per questo manuale.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta solo il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi di file di runbook e i prefissi di ticket sono fuori ambito.
Vedere anche
Sezione intitolata “Vedere anche”- Security — NextPDF Enterprise — la pagina della funzionalità per questa superficie.
- Firma con modulo di sicurezza hardware (PKCS#11) — passaggi di setup, configurazione e verifica.
- Policy crittografica FIPS 140 — la pagina della funzionalità FIPS.
- HSM — Riferimento approfondito — il riferimento mirato sul firmatario.
- FIPS 140 — Riferimento approfondito — il riferimento mirato sul modulo FIPS.
- Security — NextPDF Pro — la superficie di sicurezza di tier Pro.
- Security — NextPDF Core — la baseline di sicurezza di Core.